const SAFE = new Set(["rate_limited", "provider_not_configured"]);
const CAREFUL = new Set([
"provider_rate_limited",
"provider_unavailable",
"provider_response_unconfirmed",
"accounting_response_unconfirmed",
]);
async function withRetries(call, { interactive = false } = {}) {
for (let attempt = 0; ; attempt++) {
try {
return await call();
} catch (error) {
const retryable = SAFE.has(error.code) || (interactive && CAREFUL.has(error.code));
if (!retryable || attempt >= 2) throw error;
const backoff = (error.retryAfter ?? 2 * 4 ** attempt) * 1000;
await new Promise((resolve) => setTimeout(resolve, backoff + Math.random() * 500));
}
}
}
// Usage, with the finowl() helper from the Errors page:
const result = await withRetries(
() => finowl("/v1/breaches/password", { password }),
{ interactive: true },
);