2021-05-06 22:29:34 -07:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
exports = module.exports = promiseRetry;
|
|
|
|
|
|
|
|
|
|
const assert = require('assert'),
|
2023-05-14 10:53:50 +02:00
|
|
|
timers = require('timers/promises'),
|
2021-05-06 22:29:34 -07:00
|
|
|
util = require('util');
|
|
|
|
|
|
|
|
|
|
async function promiseRetry(options, asyncFunction) {
|
|
|
|
|
assert.strictEqual(typeof options, 'object');
|
|
|
|
|
assert(util.types.isAsyncFunction(asyncFunction));
|
|
|
|
|
|
|
|
|
|
const { times, interval } = options;
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < times; i++) {
|
|
|
|
|
try {
|
2021-12-08 10:19:16 -08:00
|
|
|
return await asyncFunction(i+1 /* attempt */);
|
2021-05-06 22:29:34 -07:00
|
|
|
} catch (error) {
|
|
|
|
|
if (i === times - 1) throw error;
|
2022-01-06 11:05:08 -08:00
|
|
|
if (options.retry && !options.retry(error)) throw error; // no more retry
|
2021-12-07 11:14:24 -08:00
|
|
|
if (options.debug) options.debug(`Attempt ${i+1} failed. Will retry: ${error.message}`);
|
2023-05-14 10:53:50 +02:00
|
|
|
await timers.setTimeout(interval);
|
2021-05-06 22:29:34 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|