Retry-After Header Backoff
Interpret a Retry-After header as seconds or an HTTP date and cap the delay before the next retry attempt.
Code
export function retryDelay(header, { now = Date.now(), maxDelayMs = 60000, fallbackMs = 1000 } = {}) {
if (header === undefined || header === null || String(header).trim() === '') return fallbackMs;
const raw = String(header).trim();
if (/^\d+$/.test(raw)) {
return Math.min(Number(raw) * 1000, maxDelayMs);
}
const when = Date.parse(raw);
if (Number.isNaN(when)) return fallbackMs;
return Math.min(Math.max(when - now, 0), maxDelayMs);
}
export async function fetchWithRetry(url, options = {}, maxAttempts = 3) {
let lastError;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
const res = await fetch(url, options);
if (res.status !== 429 && res.status < 500) return res;
if (attempt === maxAttempts) return res;
lastError = res;
const delay = retryDelay(res.headers.get('retry-after'));
await new Promise((resolve) => setTimeout(resolve, delay));
}
throw lastError;
}Report a problem with this exampleOpens a pre-filled issue on GitHub.