Retry Budget With Total Deadline
A retry policy that stops when the total deadline is reached instead of retrying a fixed count, returning the last error and the attempt log.
Code
export async function withRetryBudget(call, options) {
const {
deadlineMs,
delayMs = 100,
now = () => Date.now(),
sleep = (ms) => new Promise((r) => setTimeout(r, ms)),
} = options;
if (!Number.isFinite(deadlineMs) || deadlineMs <= 0) {
throw new RangeError("deadlineMs must be a positive number");
}
const start = now();
const attempts = [];
let lastError = null;
while (true) {
const elapsed = now() - start;
if (elapsed >= deadlineMs) {
return { ok: false, reason: "deadline-exceeded", attempts, lastError };
}
const attemptNo = attempts.length + 1;
try {
const value = await call(attemptNo);
attempts.push({ attempt: attemptNo, ok: true });
return { ok: true, value, attempts };
} catch (err) {
attempts.push({ attempt: attemptNo, ok: false, error: String(err) });
lastError = err;
const remaining = deadlineMs - (now() - start);
if (remaining <= delayMs) {
return { ok: false, reason: "deadline-exceeded", attempts, lastError };
}
await sleep(delayMs);
}
}
}Report a problem with this exampleOpens a pre-filled issue on GitHub.