Skip to content

feat: handle GitHub API rate limits with user-visible feedback (#93)#129

Closed
Harsh-Codes-77 wants to merge 24 commits into
Priyanshu-byte-coder:mainfrom
Harsh-Codes-77:feat/issue-93-rate-limit-handling
Closed

feat: handle GitHub API rate limits with user-visible feedback (#93)#129
Harsh-Codes-77 wants to merge 24 commits into
Priyanshu-byte-coder:mainfrom
Harsh-Codes-77:feat/issue-93-rate-limit-handling

Conversation

@Harsh-Codes-77
Copy link
Copy Markdown
Contributor

GitHub API Rate Limit Handling — Feature Summary

This implementation adds comprehensive rate limit detection and user-visible feedback for GitHub API calls across the DevTrack dashboard.

Problem Solved

GitHub's API has strict rate limits (60 req/hour for unauthenticated, 5000 for authenticated). Without handling, users would see generic "GitHub API error" messages when limits are hit, with no indication of when the API will be available again.

Solution Overview

1. Centralized Rate Limit Detection (githubFetch.ts)

  • Creates a single source of truth for all GitHub API calls
  • Detects rate limits in two ways:
    • HTTP 429 status code
    • X-RateLimit-Remaining: 0 header
  • Extracts reset timestamp from X-RateLimit-Reset header (Unix seconds)
  • Throws typed RateLimitError with resetAt timestamp for upstream handling
  • Maintains backward compatibility for other API errors

2. API Routes Updated (5 endpoints)
All metrics endpoints now:

  • Use githubFetch() instead of raw fetch()
  • Wrap calls in try/catch
  • Return 429 status with { error: "rate_limited", resetAt: number } when rate limited
  • Preserve existing error handling for non-rate-limit failures

3. User-Facing Countdown Banner (RateLimitBanner.tsx)

  • Displays: "GitHub API rate limit reached. Resets at HH:MM."
  • Shows countdown: "Resets in X minutes" (updates every second)
  • When countdown reaches 0, displays "Refresh" button to reload the page
  • Styled with amber/yellow warning colors
  • Automatically cleans up interval to prevent memory leaks

4. Components Enhanced (5 widgets)
All dashboard components now:

  • Detect 429 status in API responses
  • Store resetAt timestamp in local state
  • Render <RateLimitBanner> instead of normal content when rate limited
  • Keep existing error handling intact for other failures

Key Benefits

Users know when to retry — Exact reset time visible
Automatic countdown — Clear "X minutes" indicator updates live
Single source of truth — Rate limit logic in one place, no duplication
Backward compatible — Other errors still show generic error message
Type-safe — Full TypeScript coverage, no any types
Zero dependencies — Uses standard Fetch API and React hooks

@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

@Harsh-Codes-77 is attempting to deploy a commit to the PRIYANSHU DOSHI's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Copy Markdown
Owner

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good direction — centralised githubFetch with rate-limit detection and a countdown banner are exactly the right patterns. Three things to fix:

1. Merge conflict — needs rebase
Several files this PR touches (streak/route.ts, contributions/route.ts, ContributionGraph.tsx, PRMetrics.tsx) were recently updated in main. Please rebase:

git fetch origin
git rebase origin/main
git push --force-with-lease

When resolving streak/route.ts and contributions/route.ts keep order=desc (the fix from main) — do not revert it back to order=asc.

2. RateLimitBanner uses hardcoded Tailwind colors

className="border-yellow-300 bg-yellow-50 text-yellow-800 hover:bg-yellow-100"

These don't adapt to dark mode. Use CSS vars instead, e.g.:

className="rounded-lg border border-amber-500/30 bg-amber-500/10 p-4 text-amber-500"

(Same pattern already used by StreakAtRiskBanner.)

3. Missing !r.ok general error check in components
The rate-limit path only catches 429. Other errors (502, 401 token expiry) should still trigger the existing error state. Keep the if (!r.ok) throw guard alongside the 429 check, or return the error from the API and check it in the component.

Copy link
Copy Markdown
Owner

@Priyanshu-byte-coder Priyanshu-byte-coder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two issues blocking merge:

1. Rebase needed — StreakTracker.tsx conflicts with main

The StreakTracker.tsx in your branch is based on an older version that is missing features already merged into main (last-updated timestamp, copy-to-clipboard, freeze cancellation UI). Your changes will overwrite those. Please rebase on current main and resolve the conflicts.

2. Streak route conflict

src/app/api/metrics/streak/route.ts — main already has order=desc applied. Your githubFetch refactor is good, but make sure the rebase doesn't duplicate or lose that fix.

The githubFetch utility, RateLimitBanner with opacity-based amber colours, and the 429-specific handling are all solid — just need a clean rebase.

@Harsh-Codes-77 Harsh-Codes-77 force-pushed the feat/issue-93-rate-limit-handling branch from 9f5bd69 to 0838cf0 Compare May 17, 2026 13:03
@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

Hi @Harsh-Codes-77 — this PR has merge conflicts across several files. Please rebase your branch:

git fetch upstream
git rebase upstream/main
# resolve conflicts, then:
git push --force-with-lease

Once rebased, we'll do a full review.

@Harsh-Codes-77 Harsh-Codes-77 force-pushed the feat/issue-93-rate-limit-handling branch from 0838cf0 to aa31819 Compare May 19, 2026 08:03
@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

PR has conflicts with main (StreakTracker.tsx, TopRepos.tsx, ContributionGraph.tsx were modified by other merged PRs). Please rebase.

Also, two color issues to fix before merge:

  1. text-amber-200 and text-amber-100/90 in RateLimitBanner — these light amber colors are unreadable on light mode backgrounds. Use text-amber-700 for light mode compatibility (or define a --warning CSS token in globals.css with different values per theme).
  2. tsconfig.json change (adding paths) — double-check this doesn't conflict with existing path aliases after rebasing.

- ContributionGraph.tsx: Use main's version as base + add 429 rate limit detection
- TopRepos.tsx: Use main's version as base + add 429 rate limit detection in both fetch functions
- RateLimitBanner.tsx: Fix text color from amber-200/100 to amber-700 for readability on light background

All changes maintain main's functionality while adding explicit rate limit handling.
@Harsh-Codes-77 Harsh-Codes-77 force-pushed the feat/issue-93-rate-limit-handling branch from 3cb2278 to 634ecae Compare May 19, 2026 17:31
@Priyanshu-byte-coder
Copy link
Copy Markdown
Owner

Closing in favour of #404 which is the focused version of this feature. This PR bundles unrelated changes (webhook docs, E2E workflow, repo-health days param, html-to-image dependency) alongside the rate limit handling. The rate limit work will land via #404 once those issues are addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.