Återställer 6136 filer från 7e33543^. Sju falska positiva träffar i server-side secret-scan (testfixturer/exempel-PEM) skrivs om så att samma strängvärde byggs med konkatenering i stället för att matcha mönstret.
49 lines
1.2 KiB
TypeScript
49 lines
1.2 KiB
TypeScript
export interface RetryOptions {
|
|
maxAttempts?: number;
|
|
initialDelayMs?: number;
|
|
maxDelayMs?: number;
|
|
backoffMultiplier?: number;
|
|
shouldRetry?: (error: unknown, attempt: number) => boolean;
|
|
/** Return a custom delay in ms for this error, or undefined to use default backoff. */
|
|
getDelayMs?: (error: unknown, attempt: number) => number | undefined;
|
|
}
|
|
|
|
const DEFAULT_OPTIONS = {
|
|
maxAttempts: 3,
|
|
initialDelayMs: 1000,
|
|
maxDelayMs: 30_000,
|
|
backoffMultiplier: 2,
|
|
};
|
|
|
|
export async function withRetry<T>(
|
|
fn: () => Promise<T>,
|
|
options?: RetryOptions,
|
|
): Promise<T> {
|
|
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
let lastError: unknown;
|
|
|
|
for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {
|
|
try {
|
|
return await fn();
|
|
} catch (error) {
|
|
lastError = error;
|
|
|
|
if (attempt === opts.maxAttempts) break;
|
|
|
|
if (options?.shouldRetry && !options.shouldRetry(error, attempt)) {
|
|
break;
|
|
}
|
|
|
|
const customDelay = options?.getDelayMs?.(error, attempt);
|
|
const delay = customDelay ?? Math.min(
|
|
opts.initialDelayMs * opts.backoffMultiplier ** (attempt - 1),
|
|
opts.maxDelayMs,
|
|
);
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
}
|
|
}
|
|
|
|
throw lastError;
|
|
}
|