Purrx

Classify errors before you handle them

Sort Gemini API failures into kinds: a 429 rate limit worth waiting out, a used-up daily quota that never recovers, overloads, timeouts and bad requests, each with the right response.

12 min+35 XPHands-on

Your pipeline works when everything goes right. In production, things go wrong every day: Gemini is overloaded at peak times, free keys hit their limits, networks drop. The first step to handling that well is not retrying. It's recognizing what happened.

ErrorkindWhat to do
429 + retry delayrate_limitwait, then retry
429 “limit: 0” / per dayquota_exhaustedstop (or try another model)
500, 502, 503, 504overloadedretry, then fall back
timeout / networktimeout · networkretry
400bad_requeststop: fix the request
401, 403authstop: check the key
Classify first, then decide. Retrying a bad request or a used-up quota only wastes time and money.

Two very different 429s

HTTP 429 means "too many requests", but with Gemini it covers two opposite situations:

  • Rate limit: too many requests this minute. Wait a few seconds and it works. Google often says exactly how long, in a detail: { retryDelay: "12s" }.
  • Quota exhausted: the key has used its daily allowance, or has no access to this model at all (the message says limit: 0). Waiting a minute changes nothing. Retrying just wastes time before failing anyway.
how the details tell them apart
rate_limit        errorDetails: [{ "@type": "…RetryInfo", retryDelay: "12s" }]
quota_exhausted   message: "…limit: 0"
quota_exhausted   errorDetails: [{ "@type": "…QuotaFailure", violations: [{ quotaId: "…PerDay…" }] }]

The rest

  • 500, 502, 503, 504: the model is overloaded or broken right now. Retry, and fall back to another model if it lasts.
  • Timeouts and network errors: retry.
  • 400 (bad request), 401/403 (bad key), 404 (no such model): the same request will fail the same way every time. Stop.

Different clients report errors differently. Some set error.status, some only put it in the message, like [429 Too Many Requests]. classifyError reads both (statusFromMessage is written for you).

Key takeaways

  • Decide what kind of failure it is before deciding whether to retry.
  • A 429 can be a short rate limit (retry) or a used-up quota (don't): the details tell you which.
  • Show people a friendly message for each kind, never the raw API error.

Sign in to run the exercise

Reading is free. Writing code here needs an account so we have somewhere to keep your Gemini key and the +35 XP you are about to earn.