refactor(core/stdlib): improve retry function implementation and error handling
This commit is contained in:
@@ -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;
|
||||
|
||||
let count = 1;
|
||||
let lastError: Error = new Error('Retry failed');
|
||||
const wrappedFn = tryIt(fn);
|
||||
const delayFn = isFunction(delay) ? delay : null;
|
||||
const delayMs = delayFn ? 0 : delay as number;
|
||||
|
||||
while (count <= times) {
|
||||
const metadata = {
|
||||
count,
|
||||
stop: (error?: any) => {
|
||||
throw { [RetryEarlyExit]: error };
|
||||
},
|
||||
const stop = (error?: any): never => {
|
||||
throw new RetryEarlyExitError(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)
|
||||
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!;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user