[6a3a178] | 1 | # p-retry [![Build Status](https://travis-ci.org/sindresorhus/p-retry.svg?branch=master)](https://travis-ci.org/sindresorhus/p-retry)
|
---|
| 2 |
|
---|
| 3 | > Retry a promise-returning or async function
|
---|
| 4 |
|
---|
| 5 | It does exponential backoff and supports custom retry strategies for failed operations.
|
---|
| 6 |
|
---|
| 7 |
|
---|
| 8 | ## Install
|
---|
| 9 |
|
---|
| 10 | ```
|
---|
| 11 | $ npm install p-retry
|
---|
| 12 | ```
|
---|
| 13 |
|
---|
| 14 |
|
---|
| 15 | ## Usage
|
---|
| 16 |
|
---|
| 17 | ```js
|
---|
| 18 | const pRetry = require('p-retry');
|
---|
| 19 | const fetch = require('node-fetch');
|
---|
| 20 |
|
---|
| 21 | const run = async () => {
|
---|
| 22 | const response = await fetch('https://sindresorhus.com/unicorn');
|
---|
| 23 |
|
---|
| 24 | // Abort retrying if the resource doesn't exist
|
---|
| 25 | if (response.status === 404) {
|
---|
| 26 | throw new pRetry.AbortError(response.statusText);
|
---|
| 27 | }
|
---|
| 28 |
|
---|
| 29 | return response.blob();
|
---|
| 30 | };
|
---|
| 31 |
|
---|
| 32 | (async () => {
|
---|
| 33 | console.log(await pRetry(run, {retries: 5}));
|
---|
| 34 | })();
|
---|
| 35 | ```
|
---|
| 36 |
|
---|
| 37 | With the `onFailedAttempt` option:
|
---|
| 38 |
|
---|
| 39 | ```js
|
---|
| 40 | const run = async () => {
|
---|
| 41 | const response = await fetch('https://sindresorhus.com/unicorn');
|
---|
| 42 |
|
---|
| 43 | if (response.status !== 200) {
|
---|
| 44 | throw new Error(response.statusText);
|
---|
| 45 | }
|
---|
| 46 |
|
---|
| 47 | return response.json();
|
---|
| 48 | };
|
---|
| 49 |
|
---|
| 50 | (async () => {
|
---|
| 51 | const result = await pRetry(run, {
|
---|
| 52 | onFailedAttempt: error => {
|
---|
| 53 | console.log(`Attempt ${error.attemptNumber} failed. There are ${error.retriesLeft} retries left.`);
|
---|
| 54 | // 1st request => Attempt 1 failed. There are 4 retries left.
|
---|
| 55 | // 2nd request => Attempt 2 failed. There are 3 retries left.
|
---|
| 56 | // …
|
---|
| 57 | },
|
---|
| 58 | retries: 5
|
---|
| 59 | });
|
---|
| 60 |
|
---|
| 61 | console.log(result);
|
---|
| 62 | })();
|
---|
| 63 | ```
|
---|
| 64 |
|
---|
| 65 |
|
---|
| 66 | ## API
|
---|
| 67 |
|
---|
| 68 | ### pRetry(input, [options])
|
---|
| 69 |
|
---|
| 70 | 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.
|
---|
| 71 |
|
---|
| 72 | It doesn't retry on `TypeError` as that's a user error.
|
---|
| 73 |
|
---|
| 74 | #### input
|
---|
| 75 |
|
---|
| 76 | Type: `Function`
|
---|
| 77 |
|
---|
| 78 | Receives the number of attempts as the first argument and is expected to return a `Promise` or any value.
|
---|
| 79 |
|
---|
| 80 | #### options
|
---|
| 81 |
|
---|
| 82 | Type: `Object`
|
---|
| 83 |
|
---|
| 84 | Options are passed to the [`retry`](https://github.com/tim-kos/node-retry#retryoperationoptions) module.
|
---|
| 85 |
|
---|
| 86 | ##### onFailedAttempt(error)
|
---|
| 87 |
|
---|
| 88 | Type: `Function`
|
---|
| 89 |
|
---|
| 90 | 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.
|
---|
| 91 |
|
---|
| 92 | ### pRetry.AbortError(message|error)
|
---|
| 93 |
|
---|
| 94 | Abort retrying and reject the promise.
|
---|
| 95 |
|
---|
| 96 | ### message
|
---|
| 97 |
|
---|
| 98 | Type: `string`
|
---|
| 99 |
|
---|
| 100 | Error message.
|
---|
| 101 |
|
---|
| 102 | ### error
|
---|
| 103 |
|
---|
| 104 | Type: `Error`
|
---|
| 105 |
|
---|
| 106 | Custom error.
|
---|
| 107 |
|
---|
| 108 |
|
---|
| 109 | ## Tip
|
---|
| 110 |
|
---|
| 111 | You can pass arguments to the function being retried by wrapping it in an inline arrow function:
|
---|
| 112 |
|
---|
| 113 | ```js
|
---|
| 114 | const pRetry = require('p-retry');
|
---|
| 115 |
|
---|
| 116 | const run = async emoji => {
|
---|
| 117 | // …
|
---|
| 118 | };
|
---|
| 119 |
|
---|
| 120 | (async () => {
|
---|
| 121 | // Without arguments
|
---|
| 122 | await pRetry(run, {retries: 5});
|
---|
| 123 |
|
---|
| 124 | // With arguments
|
---|
| 125 | await pRetry(() => run('🦄'), {retries: 5});
|
---|
| 126 | })();
|
---|
| 127 | ```
|
---|
| 128 |
|
---|
| 129 |
|
---|
| 130 | ## Related
|
---|
| 131 |
|
---|
| 132 | - [p-timeout](https://github.com/sindresorhus/p-timeout) - Timeout a promise after a specified amount of time
|
---|
| 133 | - [More…](https://github.com/sindresorhus/promise-fun)
|
---|
| 134 |
|
---|
| 135 |
|
---|
| 136 | ## License
|
---|
| 137 |
|
---|
| 138 | MIT © [Sindre Sorhus](https://sindresorhus.com)
|
---|