Skip to content

Commit d5abb08

Browse files
authored
fix(api): classify stats route GitHub errors (JhaSourav07#2199)
## Description Fixes JhaSourav07#2198 ## Pillar - [x] 🛠️ Other (Bug fix, refactoring, docs) ## What changed The `/api/stats` route was returning `500 Internal Server Error` for every exception from `fetchGitHubContributions`, including normal GitHub-side cases like missing users and API rate limits. This PR mirrors the error classification already used by the dashboard API route: - GitHub not-found / could-not-resolve errors now return `404` with `User not found` - GitHub rate-limit style errors now return `403` with the existing rate-limit message - Unknown errors still fall back to `500` I also added route tests for the new not-found and rate-limit branches so the behavior stays explicit. ## Visual Preview N/A — JSON API status-code fix only. ## Local verification - `npm run test -- app/api/stats/route.test.ts` passed - `npm run format:check` passed - `npm run lint` passed with one existing warning in `components/WallOfLove.tsx` - `npm run typecheck` passed - `npm run test` passed: 83 files, 1394 tests - `npm run test:coverage` completed; current repo-wide branch coverage reports 66.98% on latest main - `npm run build` currently fails on clean `origin/main` too with only `Build failed because of webpack errors`, so that appears unrelated to this PR ## GSSoC 2026 This is raised and fixed under GSSoC 2026. Please add the relevant GSSoC/level labels if they do not sync from the issue automatically. ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [x] I have run `npm run format` / `npm run format:check` and `npm run lint` locally. - [x] I have run `npm run test` and all tests pass locally. - [x] My commits follow the Conventional Commits format. - [x] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have starred the repo. - [x] I have made sure that I have only one commit to merge in this PR. - [x] The SVG output matches the CommitPulse quality standard.
2 parents 2a6798f + d7ed035 commit d5abb08

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

app/api/stats/route.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,28 @@ describe('GET /api/stats', () => {
158158
expect(body.error).toBe('GitHub API error');
159159
});
160160

161+
it('returns 404 when GitHub reports that the user does not exist', async () => {
162+
vi.mocked(fetchGitHubContributions).mockRejectedValue(
163+
new Error('GitHub user "missing-user" not found')
164+
);
165+
166+
const response = await GET(makeRequest({ user: 'missing-user' }));
167+
168+
expect(response.status).toBe(404);
169+
const body = await response.json();
170+
expect(body.error).toBe('User not found');
171+
});
172+
173+
it('returns 403 when GitHub rate limiting bubbles up from the client', async () => {
174+
vi.mocked(fetchGitHubContributions).mockRejectedValue(new Error('API Rate Limit Exceeded'));
175+
176+
const response = await GET(makeRequest({ user: 'testuser' }));
177+
178+
expect(response.status).toBe(403);
179+
const body = await response.json();
180+
expect(body.error).toBe('GitHub API rate limit reached. Please configure GITHUB_TOKEN.');
181+
});
182+
161183
it('returns 500 with a generic message for non-Error throws', async () => {
162184
vi.mocked(fetchGitHubContributions).mockRejectedValue('something went wrong');
163185
const response = await GET(makeRequest({ user: 'testuser' }));

app/api/stats/route.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,25 @@ export async function GET(request: Request) {
7171
);
7272
} catch (error: unknown) {
7373
const message = error instanceof Error ? error.message : 'Unknown error';
74+
75+
if (
76+
message.toLowerCase().includes('not found') ||
77+
message.toLowerCase().includes('could not resolve')
78+
) {
79+
return NextResponse.json({ error: 'User not found' }, { status: 404 });
80+
}
81+
82+
if (
83+
message.toLowerCase().includes('rate limit') ||
84+
message.includes('API limit reached') ||
85+
message.includes('status 403')
86+
) {
87+
return NextResponse.json(
88+
{ error: 'GitHub API rate limit reached. Please configure GITHUB_TOKEN.' },
89+
{ status: 403 }
90+
);
91+
}
92+
7493
return NextResponse.json({ error: message }, { status: 500 });
7594
}
7695
}

0 commit comments

Comments
 (0)