refactor(core/stdlib): improve retry function implementation and error handling

This commit is contained in:
2026-03-26 06:09:54 +07:00
parent a61fb85088
commit 8d8ea734d1
+22 -16
View File
@@ -15,7 +15,12 @@ export type RetryFunction<Return> = (
},
) => Promise<Return>;
const RetryEarlyExit = Symbol('RetryEarlyExit');
class RetryEarlyExitError {
cause: any;
constructor(cause: any) {
this.cause = cause;
}
}
/**
* @name retry
@@ -50,24 +55,25 @@ export async function retry<Return>(
shouldRetry,
} = options;
const wrappedFn = tryIt(fn);
const delayFn = isFunction(delay) ? delay : null;
const delayMs = delayFn ? 0 : delay as number;
const stop = (error?: any): never => {
throw new RetryEarlyExitError(error);
};
let lastError: Error | null = null;
let count = 1;
let lastError: Error = new Error('Retry failed');
while (count <= times) {
const metadata = {
count,
stop: (error?: any) => {
throw { [RetryEarlyExit]: error };
},
};
const { error, data } = await tryIt(fn)(metadata);
const { error, data } = await wrappedFn({ count, stop });
if (!error)
return data;
if (RetryEarlyExit in error)
throw error[RetryEarlyExit];
if (error instanceof RetryEarlyExitError)
throw error.cause;
if (shouldRetry && !shouldRetry(error, count))
throw error;
@@ -77,12 +83,12 @@ export async function retry<Return>(
// Don't delay after the last attempt
if (count <= times) {
const delayMs = isFunction(delay) ? delay(count) : delay;
const ms = delayFn ? delayFn(count) : delayMs;
if (delayMs > 0)
await sleep(delayMs);
if (ms > 0)
await sleep(ms);
}
}
throw lastError;
throw lastError!;
}