export type RetryOptions = { maxAttempts?: number; initialDelayMs?: number; maxDelayMs?: number; backoffFactor?: number; }; export async function retryWithBackoff( operation: () => Promise, options: RetryOptions = {}, ): Promise { const { maxAttempts = 3, initialDelayMs = 5000, maxDelayMs = 20000, backoffFactor = 2, } = options; let delayMs = initialDelayMs; let lastError: Error | undefined; for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { console.log(`Attempt ${attempt} of ${maxAttempts}...`); return await operation(); } catch (error) { lastError = error instanceof Error ? error : new Error(String(error)); console.error(`Attempt ${attempt} failed:`, lastError.message); if (attempt < maxAttempts) { console.log(`Retrying in ${delayMs / 1000} seconds...`); await new Promise((resolve) => setTimeout(resolve, delayMs)); delayMs = Math.min(delayMs * backoffFactor, maxDelayMs); } } } console.error(`Operation failed after ${maxAttempts} attempts`); throw lastError; }