fetch-retry
Advanced tools
Comparing version 3.0.1 to 3.1.0
@@ -0,1 +1,3 @@ | ||
/// <reference lib="dom" /> | ||
declare module 'fetch-retry' { | ||
@@ -22,4 +24,4 @@ const _fetch: typeof fetch; | ||
function fetchBuilder(fetch: typeof _fetch): ((input: RequestInfo, init?: IRequestInitWithRetry) => Promise<Response>); | ||
function fetchBuilder(fetch: typeof _fetch, defaults?: object): ((input: RequestInfo, init?: IRequestInitWithRetry) => Promise<Response>); | ||
export = fetchBuilder; | ||
} | ||
} |
32
index.js
'use strict'; | ||
require('es6-promise').polyfill(); | ||
module.exports = function (fetch) { | ||
module.exports = function (fetch, defaults = {}) { | ||
if (typeof fetch !== 'function') { | ||
@@ -9,6 +9,30 @@ 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'); | ||
} | ||
const baseDefaults = { | ||
retries: 3, | ||
retryDelay: 1000, | ||
retryOn: [], | ||
}; | ||
defaults = Object.assign(baseDefaults, defaults); | ||
return function fetchRetry(input, init) { | ||
var retries = 3; | ||
var retryDelay = 1000; | ||
var retryOn = []; | ||
var retries = defaults.retries; | ||
var retryDelay = defaults.retryDelay; | ||
var retryOn = defaults.retryOn; | ||
@@ -15,0 +39,0 @@ if (init && init.retries !== undefined) { |
{ | ||
"name": "fetch-retry", | ||
"version": "3.0.1", | ||
"version": "3.1.0", | ||
"description": "Extend any fetch library with retry functionality", | ||
@@ -5,0 +5,0 @@ "repository": "https://github.com/jonbern/fetch-retry.git", |
@@ -18,3 +18,3 @@ # fetch-retry | ||
These properties are optional, and when omitted will default to 3 retries, a 1000ms retry delay, and to retry only on network errors. | ||
These properties are optional, and unless different defaults have been specified when requiring `fetch-retry`, these will default to 3 retries, with a 1000ms retry delay, and to only retry on network errors. | ||
@@ -40,2 +40,12 @@ ```javascript | ||
or passing your own defaults: | ||
```javascript | ||
var originalFetch = require('isomorphic-fetch'); | ||
var fetch = require('fetch-retry')(originalFetch, { | ||
retries: 5, | ||
retryDelay: 800 | ||
}); | ||
``` | ||
## Example: Exponential backoff | ||
@@ -42,0 +52,0 @@ The default behavior of `fetch-retry` is to wait a fixed amount of time between attempts, but it is also possible to customize this by passing a function as the `retryDelay` option. The function is supplied three arguments: `attempt` (starting at 0), `error` (in case of a network error), and `response`. It must return a number indicating the delay. |
@@ -18,4 +18,13 @@ 'use strict'; | ||
it('should accept defaults object as argument', function () { | ||
expect(function () { | ||
fetchBuilder(function () { }, ""); | ||
}).toThrow({ | ||
name: 'ArgumentError', | ||
message: 'defaults must be an object' | ||
}); | ||
}); | ||
it('should return fetchRetry function', function () { | ||
expect(typeof fetchBuilder(function () { })).toBe('function'); | ||
expect(typeof fetchBuilder(function () { }, {retries: 1})).toBe('function'); | ||
}); | ||
@@ -276,2 +285,106 @@ }); | ||
describe('when #defaults.retries is not a a positive integer', () => { | ||
['1', -1, 'not a number', null].forEach(invalidRetries => { | ||
it('throws error', () => { | ||
const expectedError = { | ||
name: 'ArgumentError', | ||
message: 'retries must be a positive integer' | ||
}; | ||
expect(() => { | ||
var fetchRetryWithDefaults = fetchBuilder(fetch, {retries: invalidRetries}); | ||
fetchRetryWithDefaults('http://someurl'); | ||
}).toThrow(expectedError); | ||
}); | ||
}); | ||
}); | ||
describe('when #defaults.retryDelay is not a a positive integer', () => { | ||
['1', -1, 'not a number', null].forEach(invalidDelay => { | ||
it('throws error', () => { | ||
const expectedError = { | ||
name: 'ArgumentError', | ||
message: 'retryDelay must be a positive integer or a function returning a positive integer' | ||
}; | ||
expect(() => { | ||
var fetchRetryWithDefaults = fetchBuilder(fetch, { retryDelay: invalidDelay }); | ||
fetchRetryWithDefaults('http://someurl'); | ||
}).toThrow(expectedError); | ||
}); | ||
}); | ||
}); | ||
describe('when #defaults.retryDelay is a function', function () { | ||
var defaults; | ||
var retryDelay; | ||
beforeEach(function () { | ||
retryDelay = sinon.stub().returns(5000); | ||
defaults = { | ||
retryDelay: retryDelay | ||
}; | ||
thenCallback = sinon.spy(); | ||
var fetchRetryWithDefaults = fetchBuilder(fetch, defaults); | ||
fetchRetryWithDefaults('http://someUrl') | ||
.then(thenCallback); | ||
}); | ||
}); | ||
describe('when #defaults.retryOn is not an array or function', function () { | ||
var defaults = {}; | ||
describe('when #defaults.retryOn is not an array or function', () => { | ||
it('throws exception', () => { | ||
expect(function () { | ||
defaults.retryOn = 503; | ||
var fetchRetryWithDefaults = fetchBuilder(fetch, defaults); | ||
fetchRetryWithDefaults('http://someUrl'); | ||
}).toThrow({ | ||
name: 'ArgumentError', | ||
message: 'retryOn property expects an array or function' | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('when #defaults.retries=0', function () { | ||
beforeEach(function () { | ||
thenCallback = sinon.spy(); | ||
catchCallback = sinon.spy(); | ||
var fetchRetryWithDefaults = fetchBuilder(fetch, {retries: 0}); | ||
fetchRetryWithDefaults('http://someurl') | ||
.then(thenCallback) | ||
.catch(catchCallback); | ||
}); | ||
describe('when first call is a failure', function () { | ||
beforeEach(function () { | ||
deferred1.reject(); | ||
}); | ||
describe('when rejected', function () { | ||
it('invokes the catch callback', function () { | ||
expect(catchCallback.called).toBe(true); | ||
}); | ||
it('does not call fetch again', function () { | ||
expect(fetch.callCount).toBe(1); | ||
}); | ||
}); | ||
}) | ||
}) | ||
describe('when #init.retries=1', function () { | ||
@@ -278,0 +391,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
40139
1019
100
36