Developers
Handling errors
Retry what is safe to retry, and nothing else.
Branch on error.code, not on the message: codes are stable, messages may be reworded. Retry only codes marked retryable, with exponential backoff, and honor Retry-After when present.
const RETRYABLE = new Set([
"RATE_LIMITED", "INTERNAL_ERROR", "UPSTREAM_UNAVAILABLE",
"UPSTREAM_RATE_LIMITED", "SERVICE_UNAVAILABLE",
])
async function withRetry(fn, attempts = 4) {
for (let i = 0; ; i++) {
try {
return await fn()
} catch (err) {
if (!RETRYABLE.has(err.code) || i >= attempts - 1) throw err
const wait = err.retryAfter ? err.retryAfter * 1000 : 500 * 2 ** i
await new Promise((r) => setTimeout(r, wait + Math.random() * 250))
}
}
}See the full list in Errors.
