stubborn-fetch
Advanced tools
Comparing version 0.0.4 to 0.0.5
@@ -474,13 +474,80 @@ (function(self) { | ||
function StubbornFetchError(type, message) { | ||
var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
this.type = type; | ||
this.message = message || type; | ||
this.stack = Error().stack; | ||
this.data = data; | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
function _extendableBuiltin(cls) { | ||
function ExtendableBuiltin() { | ||
var instance = Reflect.construct(cls, Array.from(arguments)); | ||
Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); | ||
return instance; | ||
} | ||
ExtendableBuiltin.prototype = Object.create(cls.prototype, { | ||
constructor: { | ||
value: cls, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
} | ||
}); | ||
if (Object.setPrototypeOf) { | ||
Object.setPrototypeOf(ExtendableBuiltin, cls); | ||
} else { | ||
ExtendableBuiltin.__proto__ = cls; | ||
} | ||
return ExtendableBuiltin; | ||
} | ||
StubbornFetchError.prototype = Object.create(Error.prototype); | ||
StubbornFetchError.prototype.name = 'StubbornFetchError'; | ||
StubbornFetchError.prototype.constructor = StubbornFetchError; | ||
var ExtendableError = function (_extendableBuiltin2) { | ||
_inherits(ExtendableError, _extendableBuiltin2); | ||
function ExtendableError(message) { | ||
_classCallCheck(this, ExtendableError); | ||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ExtendableError).call(this, message)); | ||
_this.name = _this.constructor.name; | ||
_this.message = message; | ||
if (typeof Error.captureStackTrace === 'function') { | ||
Error.captureStackTrace(_this, _this.constructor); | ||
} else { | ||
_this.stack = new Error(message).stack; | ||
} | ||
return _this; | ||
} | ||
return ExtendableError; | ||
}(_extendableBuiltin(Error)); | ||
var index_es5 = ExtendableError; | ||
function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var StubbornFetchError = function (_ExtendableError) { | ||
_inherits$1(StubbornFetchError, _ExtendableError); | ||
function StubbornFetchError(type, message) { | ||
var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
_classCallCheck$1(this, StubbornFetchError); | ||
var _this = _possibleConstructorReturn$1(this, _ExtendableError.call(this, message || type)); | ||
_this.type = type; | ||
_this.data = data; | ||
return _this; | ||
} | ||
return StubbornFetchError; | ||
}(index_es5); | ||
StubbornFetchError.types = { | ||
@@ -494,3 +561,2 @@ TIMEOUT: 'Timeout', | ||
}; | ||
var ErrorFactory = { | ||
@@ -519,3 +585,3 @@ TIMEOUT: function TIMEOUT() { | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -538,2 +604,3 @@ var TimingFunctions = { | ||
* @property minimumStatusCodeForRetry - The lowest HTTP status code for which we will retry a request. | ||
* @property unretryableStatusCodes - An array of status code numbers for which we will never retry a request, even if it's above the `minimumStatusCodeForRetry`. | ||
* @property retryOnNetworkFailure - Whether we should retry a request when it fails due to a network issue, i.e. we did not get any response from server. | ||
@@ -563,3 +630,3 @@ * @property maxErrors - The maximum global error count we will tolerate across ALL requests. After this is hit, NO future requests will be sent. | ||
_classCallCheck(this, StubbornFetchRequest); | ||
_classCallCheck$2(this, StubbornFetchRequest); | ||
@@ -572,2 +639,3 @@ this.options = { | ||
minimumStatusCodeForRetry: 400, | ||
unretryableStatusCodes: [401, 403, 422], | ||
retryOnNetworkFailure: false | ||
@@ -631,11 +699,7 @@ }; | ||
case 'HTTP': | ||
switch (error.data.response.status) { | ||
case 401: | ||
case 422: | ||
errorIsRetryable = false; | ||
break; | ||
default: | ||
errorIsRetryable = error.data.response.status >= this.options.minimumStatusCodeForRetry; | ||
{ | ||
var status = error.data.response && error.data.response.status; | ||
errorIsRetryable = typeof status === 'number' && !this.options.unretryableStatusCodes.includes(status) && status >= this.options.minimumStatusCodeForRetry; | ||
break; | ||
} | ||
break; | ||
default: | ||
@@ -693,19 +757,24 @@ errorIsRetryable = false; | ||
// Error-specific logic | ||
switch (e.data.response.status) { | ||
case 401: | ||
this._log('warn', '401 received', { response: e.data.response }); | ||
break; | ||
case 429: | ||
this._log('warn', 'rate limited', { response: e.data.response }); | ||
if (e.type === 'HTTP' && e.data.response) { | ||
switch (e.data.response.status) { | ||
case 401: | ||
this._log('warn', '401 received', { response: e.data.response }); | ||
break; | ||
case 429: | ||
this._log('warn', 'rate limited', { response: e.data.response }); | ||
// Adjust next retry time if response headers give us some hints | ||
if (e.data.response.headers.get('Retry-After')) { | ||
StubbornFetchRequest.rateLimitedUntil = Date.now() + parseInt(e.data.response.headers.get('Retry-After'), 10) * 1000; | ||
// Does this push us beyond the time limit? | ||
if (this.options.totalRequestTimeLimit && StubbornFetchRequest.rateLimitedUntil - this.startTime > this.options.totalRequestTimeLimit) { | ||
this.error = ErrorFactory.RATE_LIMITED(); | ||
this.rejectImmediately(this.error); | ||
// Adjust next retry time if response headers give us some hints | ||
if (e.data.response && e.data.response.headers && e.data.response.headers.get('Retry-After')) { | ||
StubbornFetchRequest.rateLimitedUntil = | ||
// $FlowIssue - We've already confirmed that headers object exists | ||
Date.now() + parseInt(e.data.response.headers.get('Retry-After'), 10) * 1000; | ||
// Does this push us beyond the time limit? | ||
if (this.options.totalRequestTimeLimit && StubbornFetchRequest.rateLimitedUntil - this.startTime > this.options.totalRequestTimeLimit) { | ||
this.error = ErrorFactory.RATE_LIMITED(); | ||
this.rejectImmediately(this.error); | ||
} | ||
} | ||
} | ||
break; | ||
break; | ||
} | ||
} | ||
@@ -712,0 +781,0 @@ }; |
@@ -478,13 +478,80 @@ 'use strict'; | ||
function StubbornFetchError(type, message) { | ||
var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
this.type = type; | ||
this.message = message || type; | ||
this.stack = Error().stack; | ||
this.data = data; | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
function _extendableBuiltin(cls) { | ||
function ExtendableBuiltin() { | ||
var instance = Reflect.construct(cls, Array.from(arguments)); | ||
Object.setPrototypeOf(instance, Object.getPrototypeOf(this)); | ||
return instance; | ||
} | ||
ExtendableBuiltin.prototype = Object.create(cls.prototype, { | ||
constructor: { | ||
value: cls, | ||
enumerable: false, | ||
writable: true, | ||
configurable: true | ||
} | ||
}); | ||
if (Object.setPrototypeOf) { | ||
Object.setPrototypeOf(ExtendableBuiltin, cls); | ||
} else { | ||
ExtendableBuiltin.__proto__ = cls; | ||
} | ||
return ExtendableBuiltin; | ||
} | ||
StubbornFetchError.prototype = Object.create(Error.prototype); | ||
StubbornFetchError.prototype.name = 'StubbornFetchError'; | ||
StubbornFetchError.prototype.constructor = StubbornFetchError; | ||
var ExtendableError = function (_extendableBuiltin2) { | ||
_inherits(ExtendableError, _extendableBuiltin2); | ||
function ExtendableError(message) { | ||
_classCallCheck(this, ExtendableError); | ||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ExtendableError).call(this, message)); | ||
_this.name = _this.constructor.name; | ||
_this.message = message; | ||
if (typeof Error.captureStackTrace === 'function') { | ||
Error.captureStackTrace(_this, _this.constructor); | ||
} else { | ||
_this.stack = new Error(message).stack; | ||
} | ||
return _this; | ||
} | ||
return ExtendableError; | ||
}(_extendableBuiltin(Error)); | ||
var index_es5 = ExtendableError; | ||
function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
var StubbornFetchError = function (_ExtendableError) { | ||
_inherits$1(StubbornFetchError, _ExtendableError); | ||
function StubbornFetchError(type, message) { | ||
var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
_classCallCheck$1(this, StubbornFetchError); | ||
var _this = _possibleConstructorReturn$1(this, _ExtendableError.call(this, message || type)); | ||
_this.type = type; | ||
_this.data = data; | ||
return _this; | ||
} | ||
return StubbornFetchError; | ||
}(index_es5); | ||
StubbornFetchError.types = { | ||
@@ -498,3 +565,2 @@ TIMEOUT: 'Timeout', | ||
}; | ||
var ErrorFactory = { | ||
@@ -523,3 +589,3 @@ TIMEOUT: function TIMEOUT() { | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -542,2 +608,3 @@ var TimingFunctions = { | ||
* @property minimumStatusCodeForRetry - The lowest HTTP status code for which we will retry a request. | ||
* @property unretryableStatusCodes - An array of status code numbers for which we will never retry a request, even if it's above the `minimumStatusCodeForRetry`. | ||
* @property retryOnNetworkFailure - Whether we should retry a request when it fails due to a network issue, i.e. we did not get any response from server. | ||
@@ -567,3 +634,3 @@ * @property maxErrors - The maximum global error count we will tolerate across ALL requests. After this is hit, NO future requests will be sent. | ||
_classCallCheck(this, StubbornFetchRequest); | ||
_classCallCheck$2(this, StubbornFetchRequest); | ||
@@ -576,2 +643,3 @@ this.options = { | ||
minimumStatusCodeForRetry: 400, | ||
unretryableStatusCodes: [401, 403, 422], | ||
retryOnNetworkFailure: false | ||
@@ -635,11 +703,7 @@ }; | ||
case 'HTTP': | ||
switch (error.data.response.status) { | ||
case 401: | ||
case 422: | ||
errorIsRetryable = false; | ||
break; | ||
default: | ||
errorIsRetryable = error.data.response.status >= this.options.minimumStatusCodeForRetry; | ||
{ | ||
var status = error.data.response && error.data.response.status; | ||
errorIsRetryable = typeof status === 'number' && !this.options.unretryableStatusCodes.includes(status) && status >= this.options.minimumStatusCodeForRetry; | ||
break; | ||
} | ||
break; | ||
default: | ||
@@ -697,19 +761,24 @@ errorIsRetryable = false; | ||
// Error-specific logic | ||
switch (e.data.response.status) { | ||
case 401: | ||
this._log('warn', '401 received', { response: e.data.response }); | ||
break; | ||
case 429: | ||
this._log('warn', 'rate limited', { response: e.data.response }); | ||
if (e.type === 'HTTP' && e.data.response) { | ||
switch (e.data.response.status) { | ||
case 401: | ||
this._log('warn', '401 received', { response: e.data.response }); | ||
break; | ||
case 429: | ||
this._log('warn', 'rate limited', { response: e.data.response }); | ||
// Adjust next retry time if response headers give us some hints | ||
if (e.data.response.headers.get('Retry-After')) { | ||
StubbornFetchRequest.rateLimitedUntil = Date.now() + parseInt(e.data.response.headers.get('Retry-After'), 10) * 1000; | ||
// Does this push us beyond the time limit? | ||
if (this.options.totalRequestTimeLimit && StubbornFetchRequest.rateLimitedUntil - this.startTime > this.options.totalRequestTimeLimit) { | ||
this.error = ErrorFactory.RATE_LIMITED(); | ||
this.rejectImmediately(this.error); | ||
// Adjust next retry time if response headers give us some hints | ||
if (e.data.response && e.data.response.headers && e.data.response.headers.get('Retry-After')) { | ||
StubbornFetchRequest.rateLimitedUntil = | ||
// $FlowIssue - We've already confirmed that headers object exists | ||
Date.now() + parseInt(e.data.response.headers.get('Retry-After'), 10) * 1000; | ||
// Does this push us beyond the time limit? | ||
if (this.options.totalRequestTimeLimit && StubbornFetchRequest.rateLimitedUntil - this.startTime > this.options.totalRequestTimeLimit) { | ||
this.error = ErrorFactory.RATE_LIMITED(); | ||
this.rejectImmediately(this.error); | ||
} | ||
} | ||
} | ||
break; | ||
break; | ||
} | ||
} | ||
@@ -716,0 +785,0 @@ }; |
{ | ||
"name": "stubborn-fetch", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "Fetch wrapper with built in retry", | ||
@@ -15,8 +15,10 @@ "main": "dist/index.js", | ||
"prepublish": "npm run build", | ||
"test": | ||
"./node_modules/.bin/flow && ./node_modules/.bin/jest && node ./node_modules/eslint/bin/eslint.js src/ --quiet", | ||
"test": "./node_modules/.bin/flow && ./node_modules/.bin/jest && node ./node_modules/eslint/bin/eslint.js src/ --quiet", | ||
"precommit": "lint-staged" | ||
}, | ||
"lint-staged": { | ||
"src/**/*.js": ["./node_modules/.bin/prettier --write", "git add"] | ||
"src/**/*.js": [ | ||
"./node_modules/.bin/prettier --write", | ||
"git add" | ||
] | ||
}, | ||
@@ -28,11 +30,19 @@ "pre-commit": "lint-staged", | ||
}, | ||
"keywords": ["fetch", "retry"], | ||
"keywords": [ | ||
"fetch", | ||
"retry" | ||
], | ||
"author": "Quiq", | ||
"license": "MIT", | ||
"jest": { | ||
"moduleDirectories": ["src", "node_modules"], | ||
"moduleDirectories": [ | ||
"src", | ||
"node_modules" | ||
], | ||
"testEnvironmentOptions": { | ||
"resources": "usable" | ||
}, | ||
"setupFiles": ["./jest.setup.js"] | ||
"setupFiles": [ | ||
"./jest.setup.js" | ||
] | ||
}, | ||
@@ -44,2 +54,3 @@ "bugs": { | ||
"dependencies": { | ||
"extendable-error-class": "0.1.1", | ||
"isomorphic-fetch": "2.2.1" | ||
@@ -75,3 +86,5 @@ }, | ||
}, | ||
"files": ["dist"] | ||
"files": [ | ||
"dist" | ||
] | ||
} |
@@ -100,2 +100,8 @@ # Stubborn Fetch | ||
#### `unretryableStatusCodes` - An array of status code numbers for which we will never retry a request, even if it's above the `minimumStatusCodeForRetry`. | ||
```js | ||
Array<number>; | ||
``` | ||
#### `retryOnNetworkFailure` - Whether we should retry a request when it fails due to a network issue, i.e. we did not get any response from server. | ||
@@ -102,0 +108,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
69753
1584
139
2
+ Addedextendable-error-class@0.1.1
+ Addedextendable-error-class@0.1.1(transitive)