Skip to content

apiRequest's 429 handling ignores Retry-After in HTTP-date form, and its || "Rate limited..." fallback message is dead code #572

Description

@chonilius

Problem

src/lib/api.ts → apiRequest(), from the rate-limit handling added in #44:

if (res.status === 429) {
  const retryAfter = res.headers.get("Retry-After");
  const seconds = retryAfter ? parseInt(retryAfter, 10) : NaN;
  const waitMsg = Number.isFinite(seconds)
    ? ` Please wait ${seconds} second${seconds === 1 ? "" : "s"} before trying again.`
    : "";
  throw new ApiRequestError(
    `You're doing that too fast.${waitMsg}` || `Rate limited. Please try again later.`,
    429,
    Number.isFinite(seconds) ? seconds : undefined,
  );
}
  1. HTTP-date Retry-After is dropped. RFC 9110 §10.2.3 allows Retry-After to be either delay-seconds or an HTTP-date, such as Retry-After: Wed, 21 Oct 2026 07:28:00 GMT, which proxies and CDNs commonly send. parseInt("Wed, 21 Oct…", 10) is NaN, so the wait time disappears from both the message and ApiRequestError.retryAfter. Callers that read retryAfter to throttle retries get undefined.
  2. The fallback message is unreachable. The left side of || is a template literal that always starts with "You're doing that too fast.", so it's always truthy. "Rate limited. Please try again later." can never be used, which suggests the intended "no wait info" message was lost.

Suggested fix

  • Parse both forms. Use the seconds if /^\d+$/ matches. Otherwise use Date.parse(value) and compute Math.max(0, Math.ceil((date - Date.now()) / 1000)).
  • Choose the message explicitly: the "wait N seconds" wording when seconds are known, and the plain fallback otherwise. Remove the dead ||.
  • Add unit tests for delay-seconds, an HTTP-date, a missing header and a garbage header value. lib/api.ts has limited coverage (lib/api.ts (request dedup, timeout, rate-limit handling) has zero test coverage #370).

Related: #44, #370.

No activity

Activity on this issue will appear here.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or requestgood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions