UNPKG

@augment-vir/common

Version:

A collection of augments, helpers types, functions, and classes for any JavaScript environment.

65 lines (64 loc) 2.15 kB
import { ensureErrorAndPrependMessage, wait } from '@augment-vir/core'; /** * Calls `callback` until it doesn't throw an error or throws an error when `maxRetries` is reached. * Similar to the `waitUntil` guard from '@augment-vir/assert' but doesn't check the callback's * output. * * @category Function * @category Package : @augment-vir/common * @example * * ```ts * import {callWithRetries} from '@augment-vir/common'; * * const result = callWithRetries(5, () => { * if (Math.random() < 0.5) { * return 'done'; * } else { * throw new Error(); * } * }); * ``` * * @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common) */ export function retry(maxRetries, callback, options = {}) { return internalRetry(0, maxRetries, callback, options); } function internalRetry(currentRetry, maxRetries, callback, options = {}) { try { const result = callback({ retryCount: currentRetry, isFirstExecution: currentRetry === 0, isFirstRetry: currentRetry === 1, isLastRetry: currentRetry === maxRetries, }); if (result instanceof Promise) { return result.catch(async (error) => { if (currentRetry >= maxRetries) { throw ensureErrorAndPrependMessage(error, 'Retry max reached'); } else { if (options.interval) { await wait(options.interval); } return internalRetry(currentRetry + 1, maxRetries, callback, options); } }); } else { return result; } } catch (error) { if (currentRetry >= maxRetries) { throw ensureErrorAndPrependMessage(error, 'Retry max reached'); } else if (options.interval) { return wait(options.interval).then(() => internalRetry(currentRetry + 1, maxRetries, callback, options)); } else { return internalRetry(currentRetry + 1, maxRetries, callback, options); } } }