17 lines
741 B
TypeScript
17 lines
741 B
TypeScript
export async function retryTransient<T>(label: string, task: () => Promise<T>, signal?: AbortSignal): Promise<T> {
|
|
for (let attempt = 1; ; attempt += 1) {
|
|
signal?.throwIfAborted();
|
|
try {
|
|
return await task();
|
|
} catch (cause) {
|
|
signal?.throwIfAborted();
|
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
// Storage quorum failures can recover when a disconnected replica rejoins.
|
|
if (attempt >= 3 || !/timed out|timeout|unexpected error has occurred|could not reach quorum|network error: not connected/i.test(message)) {
|
|
throw new Error(`${label}: ${message}`, { cause });
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, attempt * 1_000));
|
|
}
|
|
}
|
|
}
|