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>;
|
) => 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;
|
||||||
|
|
||||||
|
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 count = 1;
|
||||||
let lastError: Error = new Error('Retry failed');
|
|
||||||
|
|
||||||
while (count <= times) {
|
while (count <= times) {
|
||||||
const metadata = {
|
const { error, data } = await wrappedFn({ count, stop });
|
||||||
count,
|
|
||||||
stop: (error?: any) => {
|
|
||||||
throw { [RetryEarlyExit]: error };
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const { error, data } = await tryIt(fn)(metadata);
|
|
||||||
|
|
||||||
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!;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user