UNPKG

4.1 kBMarkdownView Raw
1# p-retry
2
3> Retry a promise-returning or async function
4
5It does exponential backoff and supports custom retry strategies for failed operations.
6
7## Install
8
9```sh
10npm install p-retry
11```
12
13## Usage
14
15```js
16import pRetry, {AbortError} from 'p-retry';
17import fetch from 'node-fetch';
18
19const run = async () => {
20 const response = await fetch('https://sindresorhus.com/unicorn');
21
22 // Abort retrying if the resource doesn't exist
23 if (response.status === 404) {
24 throw new AbortError(response.statusText);
25 }
26
27 return response.blob();
28};
29
30console.log(await pRetry(run, {retries: 5}));
31```
32
33## API
34
35### pRetry(input, options?)
36
37Returns 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 maximum number of retries is reached. It then rejects with the last rejection reason.
38
39It 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)
40
41#### input
42
43Type: `Function`
44
45Receives the current attempt number as the first argument and is expected to return a `Promise` or any value.
46
47#### options
48
49Type: `object`
50
51Options are passed to the [`retry`](https://github.com/tim-kos/node-retry#retryoperationoptions) module.
52
53##### onFailedAttempt(error)
54
55Type: `Function`
56
57Callback 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.
58
59```js
60import pRetry from 'p-retry';
61
62const run = async () => {
63 const response = await fetch('https://sindresorhus.com/unicorn');
64
65 if (!response.ok) {
66 throw new Error(response.statusText);
67 }
68
69 return response.json();
70};
71
72const result = await pRetry(run, {
73 onFailedAttempt: error => {
74 console.log(`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left.`);
75 // 1st request => Attempt 1 failed. There are 4 retries left.
76 // 2nd request => Attempt 2 failed. There are 3 retries left.
77 // …
78 },
79 retries: 5
80});
81
82console.log(result);
83```
84
85The `onFailedAttempt` function can return a promise. For example, you can do some async logging:
86
87```js
88import pRetry from 'p-retry';
89import logger from './some-logger';
90
91const run = async () => { … };
92
93const result = await pRetry(run, {
94 onFailedAttempt: async error => {
95 await logger.log(error);
96 }
97});
98```
99
100If the `onFailedAttempt` function throws, all retries will be aborted and the original promise will reject with the thrown error.
101
102##### signal
103
104Type: [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)
105
106You can abort retrying using [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
107
108```js
109import pRetry from 'p-retry';
110
111const run = async () => { … };
112const controller = new AbortController();
113
114cancelButton.addEventListener('click', () => {
115 controller.abort(new Error('User clicked cancel button'));
116});
117
118try {
119 await pRetry(run, {signal: controller.signal});
120} catch (error) {
121 console.log(error.message);
122 //=> 'User clicked cancel button'
123}
124```
125
126### AbortError(message)
127### AbortError(error)
128
129Abort retrying and reject the promise.
130
131### message
132
133Type: `string`
134
135An error message.
136
137### error
138
139Type: `Error`
140
141A custom error.
142
143## Tip
144
145You can pass arguments to the function being retried by wrapping it in an inline arrow function:
146
147```js
148import pRetry from 'p-retry';
149
150const run = async emoji => {
151 // …
152};
153
154// Without arguments
155await pRetry(run, {retries: 5});
156
157// With arguments
158await pRetry(() => run('🦄'), {retries: 5});
159```
160
161## Related
162
163- [p-timeout](https://github.com/sindresorhus/p-timeout) - Timeout a promise after a specified amount of time
164- [More…](https://github.com/sindresorhus/promise-fun)