p-retry
Advanced tools
Comparing version 4.6.1 to 5.0.0
137
index.d.ts
import {OperationOptions} from 'retry'; | ||
declare class AbortErrorClass extends Error { | ||
export class AbortError extends Error { | ||
readonly name: 'AbortError'; | ||
@@ -10,3 +10,3 @@ readonly originalError: Error; | ||
@param message - Error message or custom error. | ||
@param message - An error message or a custom error. | ||
*/ | ||
@@ -16,93 +16,76 @@ constructor(message: string | Error); | ||
declare namespace pRetry { | ||
interface FailedAttemptError extends Error { | ||
readonly attemptNumber: number; | ||
readonly retriesLeft: number; | ||
} | ||
export interface FailedAttemptError extends Error { | ||
readonly attemptNumber: number; | ||
readonly retriesLeft: number; | ||
} | ||
interface Options extends OperationOptions { | ||
/** | ||
Callback invoked on each retry. Receives the error thrown by `input` as the first argument with properties `attemptNumber` and `retriesLeft` which indicate the current attempt number and the number of attempts left, respectively. | ||
export interface Options extends OperationOptions { | ||
/** | ||
Callback invoked on each retry. Receives the error thrown by `input` as the first argument with properties `attemptNumber` and `retriesLeft` which indicate the current attempt number and the number of attempts left, respectively. | ||
The `onFailedAttempt` function can return a promise. For example, to add a [delay](https://github.com/sindresorhus/delay): | ||
The `onFailedAttempt` function can return a promise. For example, to add a [delay](https://github.com/sindresorhus/delay): | ||
``` | ||
import pRetry = require('p-retry'); | ||
import delay = require('delay'); | ||
``` | ||
import pRetry from 'p-retry'; | ||
import delay from 'delay'; | ||
const run = async () => { ... }; | ||
const run = async () => { ... }; | ||
(async () => { | ||
const result = await pRetry(run, { | ||
onFailedAttempt: async error => { | ||
console.log('Waiting for 1 second before retrying'); | ||
await delay(1000); | ||
} | ||
}); | ||
})(); | ||
``` | ||
const result = await pRetry(run, { | ||
onFailedAttempt: async error => { | ||
console.log('Waiting for 1 second before retrying'); | ||
await delay(1000); | ||
} | ||
}); | ||
``` | ||
If the `onFailedAttempt` function throws, all retries will be aborted and the original promise will reject with the thrown error. | ||
*/ | ||
readonly onFailedAttempt?: (error: FailedAttemptError) => void | Promise<void>; | ||
} | ||
type AbortError = AbortErrorClass; | ||
If the `onFailedAttempt` function throws, all retries will be aborted and the original promise will reject with the thrown error. | ||
*/ | ||
readonly onFailedAttempt?: (error: FailedAttemptError) => void | Promise<void>; | ||
} | ||
declare const pRetry: { | ||
/** | ||
Returns a `Promise` that is fulfilled when calling `input` returns a fulfilled promise. If calling `input` returns a rejected promise, `input` is called again until the max retries are reached, it then rejects with the last rejection reason. | ||
/** | ||
Returns a `Promise` that is fulfilled when calling `input` returns a fulfilled promise. If calling `input` returns a rejected promise, `input` is called again until the max retries are reached, it then rejects with the last rejection reason. | ||
Does not retry on most `TypeErrors`, with the exception of network errors. This is done on a best case basis as different browsers have different [messages](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful) to indicate this. | ||
See [whatwg/fetch#526 (comment)](https://github.com/whatwg/fetch/issues/526#issuecomment-554604080) | ||
Does not retry on most `TypeErrors`, with the exception of network errors. This is done on a best case basis as different browsers have different [messages](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful) to indicate this. | ||
See [whatwg/fetch#526 (comment)](https://github.com/whatwg/fetch/issues/526#issuecomment-554604080) | ||
@param input - Receives the number of attempts as the first argument and is expected to return a `Promise` or any value. | ||
@param options - Options are passed to the [`retry`](https://github.com/tim-kos/node-retry#retryoperationoptions) module. | ||
@param input - Receives the number of attempts as the first argument and is expected to return a `Promise` or any value. | ||
@param options - Options are passed to the [`retry`](https://github.com/tim-kos/node-retry#retryoperationoptions) module. | ||
@example | ||
``` | ||
import pRetry = require('p-retry'); | ||
import fetch from 'node-fetch'; | ||
@example | ||
``` | ||
import pRetry from 'p-retry'; | ||
import fetch from 'node-fetch'; | ||
const run = async () => { | ||
const response = await fetch('https://sindresorhus.com/unicorn'); | ||
const run = async () => { | ||
const response = await fetch('https://sindresorhus.com/unicorn'); | ||
// Abort retrying if the resource doesn't exist | ||
if (response.status === 404) { | ||
throw new pRetry.AbortError(response.statusText); | ||
} | ||
// Abort retrying if the resource doesn't exist | ||
if (response.status === 404) { | ||
throw new pRetry.AbortError(response.statusText); | ||
} | ||
return response.blob(); | ||
}; | ||
return response.blob(); | ||
}; | ||
(async () => { | ||
console.log(await pRetry(run, {retries: 5})); | ||
console.log(await pRetry(run, {retries: 5})); | ||
// With the `onFailedAttempt` option: | ||
const result = await pRetry(run, { | ||
onFailedAttempt: error => { | ||
console.log(`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left.`); | ||
// 1st request => Attempt 1 failed. There are 4 retries left. | ||
// 2nd request => Attempt 2 failed. There are 3 retries left. | ||
// … | ||
}, | ||
retries: 5 | ||
}); | ||
// With the `onFailedAttempt` option: | ||
const result = await pRetry(run, { | ||
onFailedAttempt: error => { | ||
console.log(`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left.`); | ||
// 1st request => Attempt 1 failed. There are 4 retries left. | ||
// 2nd request => Attempt 2 failed. There are 3 retries left. | ||
// … | ||
}, | ||
retries: 5 | ||
}); | ||
console.log(result); | ||
})(); | ||
``` | ||
*/ | ||
<T>( | ||
input: (attemptCount: number) => PromiseLike<T> | T, | ||
options?: pRetry.Options | ||
): Promise<T>; | ||
AbortError: typeof AbortErrorClass; | ||
// TODO: remove this in the next major version | ||
default: typeof pRetry; | ||
}; | ||
export = pRetry; | ||
console.log(result); | ||
``` | ||
*/ | ||
export default function pRetry<T>( | ||
input: (attemptCount: number) => PromiseLike<T> | T, | ||
options?: Options | ||
): Promise<T>; |
87
index.js
@@ -1,12 +0,11 @@ | ||
'use strict'; | ||
const retry = require('retry'); | ||
import retry from 'retry'; | ||
const networkErrorMsgs = [ | ||
const networkErrorMsgs = new Set([ | ||
'Failed to fetch', // Chrome | ||
'NetworkError when attempting to fetch resource.', // Firefox | ||
'The Internet connection appears to be offline.', // Safari | ||
'Network request failed' // `cross-fetch` | ||
]; | ||
'Network request failed', // `cross-fetch` | ||
]); | ||
class AbortError extends Error { | ||
export class AbortError extends Error { | ||
constructor(message) { | ||
@@ -37,50 +36,46 @@ super(); | ||
const isNetworkError = errorMessage => networkErrorMsgs.includes(errorMessage); | ||
const isNetworkError = errorMessage => networkErrorMsgs.has(errorMessage); | ||
const pRetry = (input, options) => new Promise((resolve, reject) => { | ||
options = { | ||
onFailedAttempt: () => {}, | ||
retries: 10, | ||
...options | ||
}; | ||
export default async function pRetry(input, options) { | ||
return new Promise((resolve, reject) => { | ||
options = { | ||
onFailedAttempt: () => {}, | ||
retries: 10, | ||
...options, | ||
}; | ||
const operation = retry.operation(options); | ||
const operation = retry.operation(options); | ||
operation.attempt(async attemptNumber => { | ||
try { | ||
resolve(await input(attemptNumber)); | ||
} catch (error) { | ||
if (!(error instanceof Error)) { | ||
reject(new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`)); | ||
return; | ||
} | ||
if (error instanceof AbortError) { | ||
operation.stop(); | ||
reject(error.originalError); | ||
} else if (error instanceof TypeError && !isNetworkError(error.message)) { | ||
operation.stop(); | ||
reject(error); | ||
} else { | ||
decorateErrorWithCounts(error, attemptNumber, options); | ||
try { | ||
await options.onFailedAttempt(error); | ||
} catch (error) { | ||
reject(error); | ||
operation.attempt(async attemptNumber => { | ||
try { | ||
resolve(await input(attemptNumber)); | ||
} catch (error) { | ||
if (!(error instanceof Error)) { | ||
reject(new TypeError(`Non-error was thrown: "${error}". You should only throw errors.`)); | ||
return; | ||
} | ||
if (!operation.retry(error)) { | ||
reject(operation.mainError()); | ||
if (error instanceof AbortError) { | ||
operation.stop(); | ||
reject(error.originalError); | ||
} else if (error instanceof TypeError && !isNetworkError(error.message)) { | ||
operation.stop(); | ||
reject(error); | ||
} else { | ||
decorateErrorWithCounts(error, attemptNumber, options); | ||
try { | ||
await options.onFailedAttempt(error); | ||
} catch (error) { | ||
reject(error); | ||
return; | ||
} | ||
if (!operation.retry(error)) { | ||
reject(operation.mainError()); | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
}); | ||
module.exports = pRetry; | ||
// TODO: remove this in the next major version | ||
module.exports.default = pRetry; | ||
module.exports.AbortError = AbortError; | ||
} |
{ | ||
"name": "p-retry", | ||
"version": "4.6.1", | ||
"version": "5.0.0", | ||
"description": "Retry a promise-returning or async function", | ||
"license": "MIT", | ||
"repository": "sindresorhus/p-retry", | ||
"funding": "https://github.com/sponsors/sindresorhus", | ||
"author": { | ||
"name": "Sindre Sorhus", | ||
"email": "sindresorhus@gmail.com", | ||
"url": "sindresorhus.com" | ||
"url": "https://sindresorhus.com" | ||
}, | ||
"type": "module", | ||
"exports": "./index.js", | ||
"engines": { | ||
"node": ">=8" | ||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0" | ||
}, | ||
@@ -42,11 +45,11 @@ "scripts": { | ||
"dependencies": { | ||
"@types/retry": "^0.12.0", | ||
"@types/retry": "^0.12.1", | ||
"retry": "^0.13.1" | ||
}, | ||
"devDependencies": { | ||
"ava": "^2.4.0", | ||
"delay": "^4.1.0", | ||
"tsd": "^0.10.0", | ||
"xo": "^0.25.3" | ||
"ava": "^3.15.0", | ||
"delay": "^5.0.0", | ||
"tsd": "^0.18.0", | ||
"xo": "^0.46.4" | ||
} | ||
} |
@@ -9,5 +9,5 @@ # p-retry | ||
```sh | ||
npm install p-retry | ||
``` | ||
$ npm install p-retry | ||
``` | ||
@@ -17,4 +17,4 @@ ## Usage | ||
```js | ||
const pRetry = require('p-retry'); | ||
const fetch = require('node-fetch'); | ||
import pRetry from 'p-retry'; | ||
import fetch from 'node-fetch'; | ||
@@ -32,5 +32,3 @@ const run = async () => { | ||
(async () => { | ||
console.log(await pRetry(run, {retries: 5})); | ||
})(); | ||
console.log(await pRetry(run, {retries: 5})); | ||
``` | ||
@@ -44,6 +42,4 @@ | ||
It does not retry on most `TypeError`'s, with the exception of network errors. This is done on a best case basis as different browsers have different [messages](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful) to indicate this. See [whatwg/fetch#526 (comment)](https://github.com/whatwg/fetch/issues/526#issuecomment-554604080) | ||
Does not retry on most `TypeErrors`, with the exception of network errors. This is done on a best case basis as different browsers have different [messages](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful) to indicate this. See [whatwg/fetch#526 (comment)](https://github.com/whatwg/fetch/issues/526#issuecomment-554604080) | ||
#### input | ||
@@ -68,2 +64,4 @@ | ||
```js | ||
import pRetry from 'p-retry'; | ||
const run = async () => { | ||
@@ -79,15 +77,13 @@ const response = await fetch('https://sindresorhus.com/unicorn'); | ||
(async () => { | ||
const result = await pRetry(run, { | ||
onFailedAttempt: error => { | ||
console.log(`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left.`); | ||
// 1st request => Attempt 1 failed. There are 4 retries left. | ||
// 2nd request => Attempt 2 failed. There are 3 retries left. | ||
// … | ||
}, | ||
retries: 5 | ||
}); | ||
const result = await pRetry(run, { | ||
onFailedAttempt: error => { | ||
console.log(`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left.`); | ||
// 1st request => Attempt 1 failed. There are 4 retries left. | ||
// 2nd request => Attempt 2 failed. There are 3 retries left. | ||
// … | ||
}, | ||
retries: 5 | ||
}); | ||
console.log(result); | ||
})(); | ||
console.log(result); | ||
``` | ||
@@ -98,14 +94,12 @@ | ||
```js | ||
const pRetry = require('p-retry'); | ||
const logger = require('./some-logger'); | ||
import pRetry from 'p-retry'; | ||
import logger from './some-logger'; | ||
const run = async () => { … }; | ||
(async () => { | ||
const result = await pRetry(run, { | ||
onFailedAttempt: async error => { | ||
await logger.log(error); | ||
} | ||
}); | ||
})(); | ||
const result = await pRetry(run, { | ||
onFailedAttempt: async error => { | ||
await logger.log(error); | ||
} | ||
}); | ||
``` | ||
@@ -115,4 +109,4 @@ | ||
### pRetry.AbortError(message) | ||
### pRetry.AbortError(error) | ||
### AbortError(message) | ||
### AbortError(error) | ||
@@ -125,3 +119,3 @@ Abort retrying and reject the promise. | ||
Error message. | ||
An error message. | ||
@@ -132,3 +126,3 @@ ### error | ||
Custom error. | ||
A custom error. | ||
@@ -140,3 +134,3 @@ ## Tip | ||
```js | ||
const pRetry = require('p-retry'); | ||
import pRetry from 'p-retry'; | ||
@@ -147,9 +141,7 @@ const run = async emoji => { | ||
(async () => { | ||
// Without arguments | ||
await pRetry(run, {retries: 5}); | ||
// Without arguments | ||
await pRetry(run, {retries: 5}); | ||
// With arguments | ||
await pRetry(() => run('🦄'), {retries: 5}); | ||
})(); | ||
// With arguments | ||
await pRetry(() => run('🦄'), {retries: 5}); | ||
``` | ||
@@ -156,0 +148,0 @@ |
Sorry, the diff of this file is not supported yet
Yes
10656
137
141
Updated@types/retry@^0.12.1