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>; ) => Promise<Return>;
const RetryEarlyExit = Symbol('RetryEarlyExit'); class RetryEarlyExitError {
cause: any;
constructor(cause: any) {
this.cause = cause;
}
}
/** /**
* @name retry * @name retry
@@ -50,24 +55,25 @@ export async function retry<Return>(
shouldRetry, shouldRetry,
} = options; } = options;
let count = 1; const wrappedFn = tryIt(fn);
let lastError: Error = new Error('Retry failed'); const delayFn = isFunction(delay) ? delay : null;
const delayMs = delayFn ? 0 : delay as number;
while (count <= times) { const stop = (error?: any): never => {
const metadata = { throw new RetryEarlyExitError(error);
count,
stop: (error?: any) => {
throw { [RetryEarlyExit]: error };
},
}; };
const { error, data } = await tryIt(fn)(metadata); let lastError: Error | null = null;
let count = 1;
while (count <= times) {
const { error, data } = await wrappedFn({ count, stop });
if (!error) if (!error)
return data; return data;
if (RetryEarlyExit in error) if (error instanceof RetryEarlyExitError)
throw error[RetryEarlyExit]; throw error.cause;
if (shouldRetry && !shouldRetry(error, count)) if (shouldRetry && !shouldRetry(error, count))
throw error; throw error;
@@ -77,12 +83,12 @@ export async function retry<Return>(
// Don't delay after the last attempt // Don't delay after the last attempt
if (count <= times) { if (count <= times) {
const delayMs = isFunction(delay) ? delay(count) : delay; const ms = delayFn ? delayFn(count) : delayMs;
if (delayMs > 0) if (ms > 0)
await sleep(delayMs); await sleep(ms);
} }
} }
throw lastError; throw lastError!;
} }