Skip to content

Swallowed error in rate-limit body parsing prevents debugging API response issues #4855

@AnushKamble

Description

@AnushKamble

Description

In lib/github.ts:272-275, the fetchGraphQLWithRetry function calls res.clone().json() to detect GraphQL-level rate-limit errors in the response body. If JSON parsing fails (malformed body, empty response, unexpected content-type from GitHub), the rejection is silently swallowed by .catch(() => null) with no logging.

Impact

When the GitHub GraphQL API returns a non-standard response format, the isBodyRateLimited check (lines 276-282) gracefully degrades (short-circuits on null), but the absence of any error logging creates a debugging black hole:

  • No warning or error is emitted when body parsing fails
  • The function silently proceeds to return the response
  • The only visible symptom is a downstream cryptic error (e.g., "profile fetch failed"), leaving no breadcrumb trail pointing back to the response parsing failure

Current Code

const body: unknown = await res
  .clone()
  .json()
  .catch(() => null);

Suggested Fix

const body: unknown = await res
  .clone()
  .json()
  .catch((err) => {
    console.warn('[GitHub API] Failed to parse rate-limit response body:', err?.message ?? err);
    return null;
  });

Acceptance Criteria

  • When res.clone().json() rejects, a warning is logged with error details
  • Existing graceful fallback to null is preserved
  • No breaking changes to function signature or return type
  • Console output does not leak sensitive data (no header/body content in logs)

Severity

Medium — not a crash, but a significant debug-ability gap that delays incident response.

Related

Similar patterns exist at lib/github.ts:680 and lib/github.ts:970 with the same issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions