No-nonsense retrier for fetch
or any function returning a Response
.
import fetch from 'node-fetch';
import retry from 'min-retry';
// retry(max, fetch) and retry(max)(fetch) are equivalent
const safeFetch = retry(3, fetch);
const firstUser = await safeFetch('/users/1', { method: 'GET' });
min-retry
retries up to max
attempts only if fetch
:
- returns a
Response
withstatus
429 or 500–599 - throws a
FetchError
orAbortError
If Response
includes a RateLimit-Reset
header, min-retry
waits delta-seconds
or until IMF-fixdate
to retry.
If retries exceed max
, then the original response or thrown error is passed along. This keeps min-retry
extremely transparent and composable with other handlers:
import fetch from 'node-fetch';
import retry from 'min-retry';
const raise = err => { throw err };
const rejectIfNotOkay = res => res.ok ? res : raise(new Error(res.statusText));
const obnoxiousFetch = retry(3, fetch);
// Let's say we've used up our rate limit on hollywood.example
const fetchElvisForMyBirthdayParty = () => obnoxiousFetch(`https://hollywood.example/stars/elvis_presley/schedule`, { method: 'POST' });
const birthdayParty = await fetchElvisForMyBirthdayParty();
// retry gives up after 4 calls and returns 429 response
const birthdayParty = await fetchElvisForMyBirthdayParty()
.then(rejectIfNotOkay)
.catch(scheduleLocalArtist('bob-with-a-banjo'));
// retry gives up after 4 calls and passes 429 response to rejectIfNotOkay,
// which rejects with an error so we know to schedule a local artist instead
const retry = require('min-retry');