type RetryOpts = {
attempts?: number;
baseMs?: number;
shouldRetry?: (err: unknown, attempt: number) => boolean;
};
export async function retry<T>(fn: () => Promise<T>, opts: RetryOpts = {}): Promise<T> {
const attempts = opts.attempts ?? 5;
const baseMs = opts.baseMs ?? 200;
const should = opts.shouldRetry ?? (() => true);
let lastErr: unknown;
for (let i = 1; i <= attempts; i++) {
try { return await fn(); }
catch (e) {
lastErr = e;
if (i === attempts || !should(e, i)) throw e;
const delay = baseMs * 2 ** (i - 1);
const jitter = Math.random() * delay;
await new Promise(r => setTimeout(r, delay + jitter));
}
}
throw lastErr; // unreachable, but TS wants it
}
const data = await retry(() => fetch('/api').then(r => r.json()), {
attempts: 4,
shouldRetry: (e) => !(e instanceof Response) || e.status >= 500,
});
Create a free account and build your private vault. Share publicly whenever you want.