import { logger } from './logging.js';
export interface RetryOptions {
maxAttempts?: number;
delay?: number;
backoffMultiplier?: number;
maxDelay?: number;
}
export async function withRetry<T>(
operation: () => Promise<T>,
options: RetryOptions = {}
): Promise<T> {
const {
maxAttempts = 3,
delay = 1000,
backoffMultiplier = 2,
maxDelay = 10000
} = options;
let lastError: Error;
let currentDelay = delay;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await operation();
} catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
if (attempt === maxAttempts) {
logger.error('Max retry attempts reached', {
attempts: maxAttempts,
error: lastError.message
});
throw lastError;
}
logger.warn('Operation failed, retrying', {
attempt,
maxAttempts,
delay: currentDelay,
error: lastError.message
});
await new Promise(resolve => setTimeout(resolve, currentDelay));
currentDelay = Math.min(currentDelay * backoffMultiplier, maxDelay);
}
}
throw lastError!;
}