node-ejs-renderer/node_modules/p-retry/index.js

95 lines
2.2 KiB
JavaScript
Raw Normal View History

2024-06-09 13:55:01 -04:00
import retry from 'retry';
import isNetworkError from 'is-network-error';
export class AbortError extends Error {
constructor(message) {
super();
if (message instanceof Error) {
this.originalError = message;
({message} = message);
} else {
this.originalError = new Error(message);
this.originalError.stack = this.stack;
}
this.name = 'AbortError';
this.message = message;
}
}
const decorateErrorWithCounts = (error, attemptNumber, options) => {
// Minus 1 from attemptNumber because the first attempt does not count as a retry
const retriesLeft = options.retries - (attemptNumber - 1);
error.attemptNumber = attemptNumber;
error.retriesLeft = retriesLeft;
return error;
};
export default async function pRetry(input, options) {
return new Promise((resolve, reject) => {
options = {
onFailedAttempt() {},
retries: 10,
shouldRetry: () => true,
...options,
};
const operation = retry.operation(options);
const abortHandler = () => {
operation.stop();
reject(options.signal?.reason);
};
if (options.signal && !options.signal.aborted) {
options.signal.addEventListener('abort', abortHandler, {once: true});
}
const cleanUp = () => {
options.signal?.removeEventListener('abort', abortHandler);
operation.stop();
};
operation.attempt(async attemptNumber => {
try {
const result = await input(attemptNumber);
cleanUp();
resolve(result);
} catch (error) {
try {
if (!(error instanceof Error)) {
throw new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`);
}
if (error instanceof AbortError) {
throw error.originalError;
}
if (error instanceof TypeError && !isNetworkError(error)) {
throw error;
}
decorateErrorWithCounts(error, attemptNumber, options);
if (!(await options.shouldRetry(error))) {
operation.stop();
reject(error);
}
await options.onFailedAttempt(error);
if (!operation.retry(error)) {
throw operation.mainError();
}
} catch (finalError) {
decorateErrorWithCounts(finalError, attemptNumber, options);
cleanUp();
reject(finalError);
}
}
});
});
}