Use the fetch API to run requests, implementing retries
npm install --save @ambassify/fetch-retriedYou can use the fetch api as per usual. The only thing different is the source of your fetch method. Here you use fetchRetried to create a fetch method that will use your desired config.
const fetchRetried = require('@ambassify/fetch-retried');
const fetch = fetchRetried({ delay: 100 });
fetch('https://www.google.com')
.then(resp => resp.json())
.then(json => console.log(json));All options are optional and have default values.
- delay: When using the default
exponentialbackoff, the delay used to calculate the timeout. Otherwise a method that calculated the timeout used. (default:200) - retries: The number of times to retry a request. (default:
5) - isOK: A method that determines whether a request succeeded by returning
trueorfalsewhen passed a response. (default:(resp) => resp.ok) - shouldRetryError: When fetch throws an error this method determines whether the request is retried by returning
trueorfalse(default:() => true) - retryMethods: Which HTTP verbs to retry (default:
['PUT', 'DELETE', 'GET', 'HEAD', 'PATCH', 'OPTIONS']). - shouldRetry: Allows you to override the default method to check if a retry should be tried. Takes a function that accepts the following signature:
shouldRetry(url, requestOptions, { attempts, config, error, response }). - fetch: The underlying fetch implementation to use. (default:
require('node-fetch'))
Strategies are attached to the default import of this package and can be accessed using.
const fetchRetried = require('@ambassify/fetch-retried');
fetchRetried.exponential;
// OR
fetchRetried.binaryExponential;
// Usage:
const fetch = fetchRetried({
delay: fetchRetried.exponential(10)
})
// OR
const fetch = fetchRetried({
delay: fetchRetried.binaryExponential()
})exponential
function exponential(delay) {
return (attempts) => (attempts * attempts) * delay;
}binaryExponential
function binaryExponential(delay = 1) {
return (attempts) => (Math.pow(2, attempts) - 1) * delay;
}The same building blocks the default retry logic uses are attached to the
default import, so you can reuse them when writing a custom shouldRetry.
const fetchRetried = require('@ambassify/fetch-retried');-
defaultShouldRetry(url, requestOptions, options): The default retry decision. Returnsfalseonce retries are exhausted, the response passesisOK,shouldRetryErrorrejects the error, or the method is not inretryMethods. Call it as the fallback in your ownshouldRetryto keep the default behaviour for cases you don't handle.optionsis{ attempts, config, error, response }. -
isConnectError(err): Returnstruewhen an error happened during the connection phase (DNS failure, connection refused, TLS handshake, undicionConnect*frames, or anAggregateErrorwhere every error qualifies). These requests never reached the server, so they are safe to retry even on non-idempotent methods. The recognised early-stage codes are exposed onisConnectError.EARLY_STAGE_NET_ERRORS. -
isRetryableMethod(retryMethods, method): Returnstruewhenmethod(defaultGET) is present in theretryMethodsarray. Case-insensitive. -
IDEMPOTENT_HTTP_METHODS: The defaultretryMethodsarray —['PUT', 'DELETE', 'GET', 'HEAD', 'PATCH', 'OPTIONS']. Also available asisRetryableMethod.IDEMPOTENT_HTTP_METHODS. -
hasRetriesLeft(retries, attempts): Returnsattempts < retries(retriesdefaults to5). -
isValidResponse(resp): The defaultisOK. Returnstruefor responses without a status or with a status below500(i.e. only5xxand failed requests are retried).
Retry connection errors on top of the default behaviour:
const {
isConnectError,
defaultShouldRetry,
IDEMPOTENT_HTTP_METHODS,
} = require('@ambassify/fetch-retried');
function shouldRetry(url, requestOptions, options) {
const { error } = options;
// Connection-phase errors never sent the request, retry regardless of method.
if (isConnectError(error))
return true;
return defaultShouldRetry(url, requestOptions, options);
}
const fetch = fetchRetried({
retries: 2,
shouldRetry,
retryMethods: IDEMPOTENT_HTTP_METHODS,
});We really appreciate any contribution you would like to make, so don't hesitate to report issues or submit pull requests.
This project is released under a MIT license.
If you would like to know more about us, be sure to have a look at our website, or our Twitter accounts Ambassify, Sitebase, JorgenEvens