Improve error handling for GitHub API requests#58
Improve error handling for GitHub API requests#58Rey-han-24 wants to merge 3 commits intoBeyteFlow:mainfrom
Conversation
Refactor error handling for GitHub API calls to provide more specific responses for 404 and 403 errors.
|
@Rey-han-24 is attempting to deploy a commit to the naheel0's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughReworks async assignment and adds an explicit null/undefined check for fetched repository info, returning a 400 on failure; updates the README generation error message and adds defensive handling comments around Octokit helper results without changing exported/public signatures. (≤50 words) Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/app/api/generate/route.ts (1)
65-66: Avoiderror: any; use a type guard or Octokit'sRequestErrortype.If/when the dead-code issue above is fixed,
error: anywill bypass type safety. Octokit throwsRequestError(from@octokit/request-error) which has a.statusproperty. Also,error.messageon line 66 will throw at runtime iferroris not an object.Suggested approach
- } catch (error: any) { - console.error("GitHub API Error:", error.message); - - // Handle 404 (Not Found / Typos) - if (error.status === 404) { + } catch (error: unknown) { + const status = error instanceof Error && 'status' in error ? (error as { status: number }).status : undefined; + const message = error instanceof Error ? error.message : "Unknown GitHub API error"; + console.error("GitHub API Error:", message); + + if (status === 404) {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/api/generate/route.ts` around lines 65 - 66, Replace the unsafe catch signature and logging by using a proper error type guard: change the catch parameter from "error: any" to "error: unknown" (or import RequestError from `@octokit/request-error` and use it) and in the catch block check whether the error is an instance of RequestError or an object with a "message" property; then log a safe message including error.message and, if present, error.status (and fallback to JSON.stringify or String(error) if neither is present) instead of directly accessing error.message as in the "catch (error: any)" / "console.error('GitHub API Error:', error.message)" lines so you avoid runtime errors and surface Octokit RequestError.status when available.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/api/generate/route.ts`:
- Line 184: The response body returns an object with key "error" whose value
currently redundantly starts with "error: ". Update the route handler that
constructs the JSON error response (the generate API route) to remove the
"error: " prefix so the value reads "AI generation failed. Please try again in a
moment." — keep the same "error" key and only change the message string to avoid
the stuttered "error: error: ..." output.
- Around line 59-89: The try/catch in route.ts is dead because getRepoData and
getRepoContents swallow errors and never reject; change octokit helpers instead:
remove the internal try/catch in getRepoData and getRepoContents so they throw
on error (propagating status and message), then adjust callers in route.ts
(variables repoInfo, repoContents and the downstream logic that consumes them)
to handle possibly undefined/null responses and the thrown errors via the
existing try/catch block so the 404/403 NextResponse branches work as intended.
---
Nitpick comments:
In `@src/app/api/generate/route.ts`:
- Around line 65-66: Replace the unsafe catch signature and logging by using a
proper error type guard: change the catch parameter from "error: any" to "error:
unknown" (or import RequestError from `@octokit/request-error` and use it) and in
the catch block check whether the error is an instance of RequestError or an
object with a "message" property; then log a safe message including
error.message and, if present, error.status (and fallback to JSON.stringify or
String(error) if neither is present) instead of directly accessing error.message
as in the "catch (error: any)" / "console.error('GitHub API Error:',
error.message)" lines so you avoid runtime errors and surface Octokit
RequestError.status when available.
| let repoInfo, repoContents; | ||
| try { | ||
| [repoInfo, repoContents] = await Promise.all([ | ||
| getRepoData(owner, repo), | ||
| getRepoContents(owner, repo), | ||
| ]); | ||
| } catch (error: any) { | ||
| console.error("GitHub API Error:", error.message); | ||
|
|
||
| // Handle 404 (Not Found / Typos) | ||
| if (error.status === 404) { | ||
| return NextResponse.json( | ||
| { error: "Repository not found. Please check the URL for typos or ensure the repo is public." }, | ||
| { status: 404 } | ||
| ); | ||
| } | ||
|
|
||
| // Handle 403 (Rate limits or Private repos) | ||
| if (error.status === 403) { | ||
| return NextResponse.json( | ||
| { error: "Access denied or GitHub API rate limit reached. Try again later." }, | ||
| { status: 403 } | ||
| ); | ||
| } | ||
|
|
||
| // Generic fallback for other API issues | ||
| return NextResponse.json( | ||
| { error: "Unable to reach GitHub. Please verify the repository exists and is accessible." }, | ||
| { status: 400 } | ||
| ); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find octokit.ts
find . -name "octokit.ts" -o -name "*octokit*" | head -20Repository: BeyteFlow/ReadmeGenAI
Length of output: 85
🏁 Script executed:
#!/bin/bash
# Check src/lib directory structure
ls -la src/lib/ 2>/dev/null | head -20Repository: BeyteFlow/ReadmeGenAI
Length of output: 294
🏁 Script executed:
#!/bin/bash
# Search for getRepoData and getRepoContents definitions
rg -n "async.*getRepoData|function getRepoData" -A 20 --type tsRepository: BeyteFlow/ReadmeGenAI
Length of output: 1100
🏁 Script executed:
#!/bin/bash
# Search for getRepoContents definition
rg -n "async.*getRepoContents|function getRepoContents" -A 20 --type tsRepository: BeyteFlow/ReadmeGenAI
Length of output: 1015
Critical: This try/catch is dead code — getRepoData and getRepoContents never throw.
Looking at src/lib/octokit.ts, both functions have internal try/catch blocks that swallow errors:
getRepoData(lines 20–35) catches all errors and returnsnullgetRepoContents(lines 40–58) catches all errors and returns[]
Since both promises always resolve successfully, Promise.all will never reject, so the catch block (including the 404 and 403 handling) will never execute.
To make this work, either:
- Remove the try/catch blocks in octokit.ts so errors propagate to the caller here, OR
- Modify the octokit helpers to return an error-aware result object (e.g.,
{ data: null, error: {...} }) that preserves the status code, OR - Check the null/[] return values here instead of trying to catch exceptions (though this loses the status code differentiation)
Option 1 is the simplest approach aligned with the PR's goal. After that change, update the type handling for repoInfo and repoContents downstream (lines 92–119) to account for the actual response types.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/app/api/generate/route.ts` around lines 59 - 89, The try/catch in
route.ts is dead because getRepoData and getRepoContents swallow errors and
never reject; change octokit helpers instead: remove the internal try/catch in
getRepoData and getRepoContents so they throw on error (propagating status and
message), then adjust callers in route.ts (variables repoInfo, repoContents and
the downstream logic that consumes them) to handle possibly undefined/null
responses and the thrown errors via the existing try/catch block so the 404/403
NextResponse branches work as intended.
There was a problem hiding this comment.
Pull request overview
Refactors the POST /api/generate endpoint’s GitHub repository fetch flow to provide more specific, user-facing error responses when GitHub API calls fail (notably 404 and 403), before proceeding to AI README generation.
Changes:
- Wraps
getRepoData/getRepoContentscalls in a try/catch intended to map GitHub API failures to specific HTTP responses (404/403). - Adds a generic fallback response for other GitHub API failures.
- Updates the AI generation failure message returned from the endpoint.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/app/api/generate/route.ts
Outdated
| // Generic fallback for other API issues | ||
| return NextResponse.json( | ||
| { error: "Unable to reach GitHub. Please verify the repository exists and is accessible." }, | ||
| { status: 400 } |
There was a problem hiding this comment.
The generic fallback response uses HTTP 400, but failures talking to GitHub (timeouts, upstream errors, unexpected Octokit errors) are server-side / upstream issues rather than a bad client request. Returning a 5xx (often 502/503) would be more accurate and makes retries/monitoring behave correctly.
| { status: 400 } | |
| { status: 502 } |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Refactor error handling for GitHub API calls to provide more specific responses for 404 and 403 errors.
🚀 BΞYTΞFLʘW | Pull Request Protocol
PR Type: Fix (Choose one:
feat|fix|refactor|docs|perf)Issue Link: Fixes # 37
📝 System Summary
Enhanced the repository verification pipeline by implementing a dedicated error-handling "gatekeeper" for GitHub API interactions. The system now distinguishes between invalid URLs, missing/private repositories (404), and rate-limiting issues (403), providing clear, actionable feedback to the user before initiating AI generation.
🛠️ Technical Changes
app/api/generate/route.ts......🧪 Quality Assurance (QA)
npm run buildexecuted without errors.🖼️ Visual Evidence
If this PR affects the UI, drop a screenshot or GIF below:
📡 Developer Authorization
Authorized by: @Rey-han-24
Timestamp: {{ 2/24/2026 }}