Skip to content

Commit

Permalink
Merge pull request #33 from vishalvijay/support-any-fetch
Browse files Browse the repository at this point in the history
Remove isomorphic-fetch dependency and support any fetch package
  • Loading branch information
jonbern committed Jan 20, 2020
2 parents c26ba5a + 5a2eb3c commit a84fa02
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 265 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Adds retry functionality to the `Fetch` API.

It wraps [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) and retries requests that fail due to network issues. It can also be configured to retry requests on specific HTTP status codes.
It wraps any `Fetch` API package (eg: [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch), [cross-fetch](https://github.com/lquixada/cross-fetch), [isomorphic-unfetch](https://github.com/developit/unfetch) and etc.) and retries requests that fail due to network issues. It can also be configured to retry requests on specific HTTP status codes.

[![Build Status](https://travis-ci.org/jonbern/fetch-retry.svg?branch=master)](https://travis-ci.org/jonbern/fetch-retry)

Expand All @@ -18,7 +18,8 @@ npm install fetch-retry --save
These properties are optional, and when omitted will default to 3 retries, a 1000ms retry delay, and to retry only on network errors.

```javascript
var fetch = require('fetch-retry');
var originalFetch = require('isomorphic-fetch');
var fetch = require('fetch-retry')(originalFetch);
```

```javascript
Expand Down
6 changes: 3 additions & 3 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ declare module 'fetch-retry' {
retryOn?: number[] | RequestRetryOnFunction;
}

function fetch(url: String, options?: IRequestInitWithRetry): Promise<Response>;
export = fetch;
}
function fetchBuilder(fetch: (url: String, options?: RequestInit) => Promise<Response>): ((url: String, options?: IRequestInitWithRetry) => Promise<Response>);
export = fetchBuilder;
}
123 changes: 64 additions & 59 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,81 +1,86 @@
'use strict';
require('isomorphic-fetch');
require('es6-promise').polyfill();

module.exports = function(url, options) {
var retries = 3;
var retryDelay = 1000;
var retryOn = [];
module.exports = function (fetch) {
if (typeof fetch !== 'function') {
throw new ArgumentError('fetch must be a function');
}

return function fetchRetry(url, options) {
var retries = 3;
var retryDelay = 1000;
var retryOn = [];

if (options && options.retries !== undefined) {
if (isPositiveInteger(options.retries)) {
retries = options.retries;
} else {
throw new ArgumentError('retries must be a positive integer');
if (options && options.retries !== undefined) {
if (isPositiveInteger(options.retries)) {
retries = options.retries;
} else {
throw new ArgumentError('retries must be a positive integer');
}
}
}

if (options && options.retryDelay !== undefined) {
if (isPositiveInteger(options.retryDelay) || (typeof options.retryDelay === 'function')) {
retryDelay = options.retryDelay;
} else {
throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');
if (options && options.retryDelay !== undefined) {
if (isPositiveInteger(options.retryDelay) || (typeof options.retryDelay === 'function')) {
retryDelay = options.retryDelay;
} else {
throw new ArgumentError('retryDelay must be a positive integer or a function returning a positive integer');
}
}
}

if (options && options.retryOn) {
if (Array.isArray(options.retryOn) || (typeof options.retryOn === 'function')) {
retryOn = options.retryOn;
} else {
throw new ArgumentError('retryOn property expects an array or function');
if (options && options.retryOn) {
if (Array.isArray(options.retryOn) || (typeof options.retryOn === 'function')) {
retryOn = options.retryOn;
} else {
throw new ArgumentError('retryOn property expects an array or function');
}
}
}

return new Promise(function(resolve, reject) {
var wrappedFetch = function(attempt) {
fetch(url, options)
.then(function(response) {
if (Array.isArray(retryOn) && retryOn.indexOf(response.status) === -1) {
resolve(response);
} else if (typeof retryOn === 'function') {
if (retryOn(attempt, null, response)) {
retry(attempt, null, response);
} else {
return new Promise(function (resolve, reject) {
var wrappedFetch = function (attempt) {
fetch(url, options)
.then(function (response) {
if (Array.isArray(retryOn) && retryOn.indexOf(response.status) === -1) {
resolve(response);
}
} else {
if (attempt < retries) {
retry(attempt, null, response);
} else if (typeof retryOn === 'function') {
if (retryOn(attempt, null, response)) {
retry(attempt, null, response);
} else {
resolve(response);
}
} else {
resolve(response);
if (attempt < retries) {
retry(attempt, null, response);
} else {
resolve(response);
}
}
}
})
.catch(function(error) {
if (typeof retryOn === 'function') {
if (retryOn(attempt, error, null)) {
})
.catch(function (error) {
if (typeof retryOn === 'function') {
if (retryOn(attempt, error, null)) {
retry(attempt, error, null);
} else {
reject(error);
}
} else if (attempt < retries) {
retry(attempt, error, null);
} else {
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);
}
function retry(attempt, error, response) {
var delay = (typeof retryDelay === 'function') ?
retryDelay(attempt, error, response) : retryDelay;
setTimeout(function () {
wrappedFetch(++attempt);
}, delay);
}

wrappedFetch(0);
});
wrappedFetch(0);
});
};
};

function isPositiveInteger(value) {
Expand Down
62 changes: 19 additions & 43 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
"author": "Jon K. Bernhardsen",
"license": "MIT",
"dependencies": {
"es6-promise": "^4.2.8",
"isomorphic-fetch": "^2.2.1"
"es6-promise": "^4.2.8"
},
"devDependencies": {
"body-parser": "^1.19.0",
Expand All @@ -29,9 +28,9 @@
"eslint": "^6.2.2",
"expectations": "^0.7.1",
"express": "^4.17.1",
"isomorphic-fetch": "^2.2.1",
"mocha": "^5.2.0",
"nyc": "^14.1.1",
"proxyquire": "^2.1.3",
"sinon": "^6.3.5"
}
}
3 changes: 2 additions & 1 deletion test/integration/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
chai.should();
const childProcess = require('child_process');
const fetchRetry = require('../../');
const fetch = require('isomorphic-fetch');
const fetchRetry = require('../../')(fetch);

describe('fetch-retry integration tests', () => {

Expand Down
Loading

0 comments on commit a84fa02

Please sign in to comment.