diff --git a/src/utils/retry.ts b/src/utils/retry.ts new file mode 100644 index 0000000..5de066a --- /dev/null +++ b/src/utils/retry.ts @@ -0,0 +1,32 @@ +/** + * Retry an async function with exponential backoff. + */ +export async function retry( + fn: () => Promise, + maxAttempts: number = 3, + baseDelayMs: number = 1000 +): Promise { + if (maxAttempts < 1) { + throw new Error("maxAttempts must be at least 1"); + } + + let lastError: Error | undefined; + + for (let attempt = 0; attempt < maxAttempts; attempt++) { + try { + return await fn(); + } catch (err) { + lastError = err instanceof Error ? err : new Error(String(err)); + if (attempt < maxAttempts - 1) { + const delay = baseDelayMs * Math.pow(2, attempt); + await sleep(delay); + } + } + } + + throw lastError; +} + +function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +}