123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.fetchRetry = factory());
- })(this, (function () { 'use strict';
- var fetchRetry = function (fetch, defaults) {
- defaults = defaults || {};
- if (typeof fetch !== 'function') {
- throw new ArgumentError('fetch must be a function');
- }
- if (typeof defaults !== 'object') {
- throw new ArgumentError('defaults must be an object');
- }
- if (defaults.retries !== undefined && !isPositiveInteger(defaults.retries)) {
- throw new ArgumentError('retries must be a positive integer');
- }
- if (defaults.retryDelay !== undefined && !isPositiveInteger(defaults.retryDelay) && typeof defaults.retryDelay !== 'function') {
- throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');
- }
- if (defaults.retryOn !== undefined && !Array.isArray(defaults.retryOn) && typeof defaults.retryOn !== 'function') {
- throw new ArgumentError('retryOn property expects an array or function');
- }
- var baseDefaults = {
- retries: 3,
- retryDelay: 1000,
- retryOn: [],
- };
- defaults = Object.assign(baseDefaults, defaults);
- return function fetchRetry(input, init) {
- var retries = defaults.retries;
- var retryDelay = defaults.retryDelay;
- var retryOn = defaults.retryOn;
- if (init && init.retries !== undefined) {
- if (isPositiveInteger(init.retries)) {
- retries = init.retries;
- } else {
- throw new ArgumentError('retries must be a positive integer');
- }
- }
- if (init && init.retryDelay !== undefined) {
- if (isPositiveInteger(init.retryDelay) || (typeof init.retryDelay === 'function')) {
- retryDelay = init.retryDelay;
- } else {
- throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');
- }
- }
- if (init && init.retryOn) {
- if (Array.isArray(init.retryOn) || (typeof init.retryOn === 'function')) {
- retryOn = init.retryOn;
- } else {
- throw new ArgumentError('retryOn property expects an array or function');
- }
- }
- // eslint-disable-next-line no-undef
- return new Promise(function (resolve, reject) {
- var wrappedFetch = function (attempt) {
- // As of node 18, this is no longer needed since node comes with native support for fetch:
- /* istanbul ignore next */
- var _input =
- typeof Request !== 'undefined' && input instanceof Request
- ? input.clone()
- : input;
- fetch(_input, init)
- .then(function (response) {
- if (Array.isArray(retryOn) && retryOn.indexOf(response.status) === -1) {
- resolve(response);
- } else if (typeof retryOn === 'function') {
- try {
- // eslint-disable-next-line no-undef
- return Promise.resolve(retryOn(attempt, null, response))
- .then(function (retryOnResponse) {
- if(retryOnResponse) {
- retry(attempt, null, response);
- } else {
- resolve(response);
- }
- }).catch(reject);
- } catch (error) {
- reject(error);
- }
- } else {
- if (attempt < retries) {
- retry(attempt, null, response);
- } else {
- resolve(response);
- }
- }
- })
- .catch(function (error) {
- if (typeof retryOn === 'function') {
- try {
- // eslint-disable-next-line no-undef
- Promise.resolve(retryOn(attempt, error, null))
- .then(function (retryOnResponse) {
- if(retryOnResponse) {
- retry(attempt, error, null);
- } else {
- reject(error);
- }
- })
- .catch(function(error) {
- reject(error);
- });
- } catch(error) {
- reject(error);
- }
- } else if (attempt < retries) {
- retry(attempt, error, null);
- } else {
- reject(error);
- }
- });
- };
- function retry(attempt, error, response) {
- var delay = (typeof retryDelay === 'function') ?
- retryDelay(attempt, error, response) : retryDelay;
- setTimeout(function () {
- wrappedFetch(++attempt);
- }, delay);
- }
- wrappedFetch(0);
- });
- };
- };
- function isPositiveInteger(value) {
- return Number.isInteger(value) && value >= 0;
- }
- function ArgumentError(message) {
- this.name = 'ArgumentError';
- this.message = message;
- }
- return fetchRetry;
- }));
|