2
0
mirror of https://github.com/tenrok/axios.git synced 2026-05-21 13:24:11 +03:00

Allow custom HTTP status code error ranges (#308)

Adding support for custom HTTP status code error ranges
This commit is contained in:
Nick Uraltsev
2016-04-26 13:18:58 -07:00
committed by Matt Zabriskie
parent 093593cbca
commit fa9444e0ba
7 changed files with 169 additions and 17 deletions
+20 -2
View File
@@ -261,12 +261,20 @@ These are the available config options for making requests. Only the `url` is re
// `progress` allows handling of progress events for 'POST' and 'PUT uploads'
// as well as 'GET' downloads
progress: function(progressEvent) {
progress: function (progressEvent) {
// Do whatever you want with the native progress event
},
// `maxContentLength` defines the max size of the http response content allowed
maxContentLength: 2000
maxContentLength: 2000,
// `validateStatus` defines whether to resolve or reject the promise for a given
// HTTP response status code. If `validateStatus` returns `true` (or is set to `null`
// or `undefined`), the promise will be resolved; otherwise, the promise will be
// rejected.
validateStatus: function (status) {
return status >= 200 && status < 300; // default
}
}
```
@@ -406,6 +414,16 @@ axios.get('/user/12345')
});
```
You can define a custom HTTP status code error range using the `validateStatus` config option.
```js
axios.get('/user/12345', {
validateStatus: function (status) {
return status < 500; // Reject only if the status code is greater than or equal to 500
}
})
```
## Semver
Until axios reaches a `1.0` release, breaking changes will be released with a new minor version. For example `0.5.1`, and `0.5.4` will have the same API, but `0.6.0` will have breaking changes.
+1 -7
View File
@@ -9,13 +9,7 @@ var url = require('url');
var zlib = require('zlib');
var pkg = require('./../../package.json');
var Buffer = require('buffer').Buffer;
// Resolve or reject the Promise based on the status
function settle(resolve, reject, response) {
(response.status >= 200 && response.status < 300 ?
resolve :
reject)(response);
}
var settle = require('../helpers/settle');
/*eslint consistent-return:0*/
module.exports = function httpAdapter(resolve, reject, config) {
+2 -5
View File
@@ -6,6 +6,7 @@ var parseHeaders = require('./../helpers/parseHeaders');
var transformData = require('./../helpers/transformData');
var isURLSameOrigin = require('./../helpers/isURLSameOrigin');
var btoa = (typeof window !== 'undefined' && window.btoa) || require('./../helpers/btoa');
var settle = require('../helpers/settle');
module.exports = function xhrAdapter(resolve, reject, config) {
var requestData = config.data;
@@ -73,11 +74,7 @@ module.exports = function xhrAdapter(resolve, reject, config) {
request: request
};
// Resolve or reject the Promise based on the status
((response.status >= 200 && response.status < 300) ||
(!('status' in request) && request.responseText) ?
resolve :
reject)(response);
settle(resolve, reject, response);
// Clean up request
request = null;
+5 -1
View File
@@ -58,5 +58,9 @@ module.exports = {
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1
maxContentLength: -1,
validateStatus: function validateStatus(status) {
return status >= 200 && status < 300;
}
};
+18
View File
@@ -0,0 +1,18 @@
'use strict';
/**
* Resolve or reject a Promise based on response status.
*
* @param {Function} resolve A function that resolves the promise.
* @param {Function} reject A function that rejects the promise.
* @param {object} response The response.
*/
module.exports = function settle(resolve, reject, response) {
var validateStatus = response.config.validateStatus;
// Note: status is not exposed by XDomainRequest
if (!response.status || !validateStatus || validateStatus(response.status)) {
resolve(response);
} else {
reject(response);
}
};
+75
View File
@@ -0,0 +1,75 @@
var settle = require('../../../lib/helpers/settle');
describe('helpers::settle', function() {
var resolve;
var reject;
beforeEach(function() {
resolve = jasmine.createSpy('resolve');
reject = jasmine.createSpy('reject');
});
it('should resolve promise if status is not set', function() {
var response = {
config: {
validateStatus: function() {
return true;
}
}
};
settle(resolve, reject, response);
expect(resolve).toHaveBeenCalledWith(response);
expect(reject).not.toHaveBeenCalled();
});
it('should resolve promise if validateStatus is not set', function() {
var response = {
status: 500,
config: {
}
};
settle(resolve, reject, response);
expect(resolve).toHaveBeenCalledWith(response);
expect(reject).not.toHaveBeenCalled();
});
it('should resolve promise if validateStatus returns true', function() {
var response = {
status: 500,
config: {
validateStatus: function() {
return true;
}
}
};
settle(resolve, reject, response);
expect(resolve).toHaveBeenCalledWith(response);
expect(reject).not.toHaveBeenCalled();
});
it('should reject promise if validateStatus returns false', function() {
var response = {
status: 500,
config: {
validateStatus: function() {
return false;
}
}
};
settle(resolve, reject, response);
expect(resolve).not.toHaveBeenCalled();
expect(reject).toHaveBeenCalledWith(response);
});
it('should pass status to validateStatus', function() {
var validateStatus = jasmine.createSpy('validateStatus');
var response = {
status: 500,
config: {
validateStatus: validateStatus
}
};
settle(resolve, reject, response);
expect(validateStatus).toHaveBeenCalledWith(500);
});
});
+48 -2
View File
@@ -55,6 +55,52 @@ describe('requests', function () {
.then(finish, finish);
});
it('should reject when validateStatus returns false', function (done) {
var resolveSpy = jasmine.createSpy('resolve');
var rejectSpy = jasmine.createSpy('reject');
axios('/foo', {
validateStatus: function (status) {
return status !== 500;
}
}).then(resolveSpy)
.catch(rejectSpy)
.then(function () {
expect(resolveSpy).not.toHaveBeenCalled();
expect(rejectSpy).toHaveBeenCalled();
done();
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 500
});
});
});
it('should resolve when validateStatus returns true', function (done) {
var resolveSpy = jasmine.createSpy('resolve');
var rejectSpy = jasmine.createSpy('reject');
axios('/foo', {
validateStatus: function (status) {
return status === 500;
}
}).then(resolveSpy)
.catch(rejectSpy)
.then(function () {
expect(resolveSpy).toHaveBeenCalled();
expect(rejectSpy).not.toHaveBeenCalled();
done();
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 500
});
});
});
it('should make cross domian http request', function (done) {
var response;
@@ -71,7 +117,7 @@ describe('requests', function () {
'Content-Type': 'application/json'
}
});
setTimeout(function () {
expect(response.data.foo).toEqual('bar');
expect(response.status).toEqual(200);
@@ -200,7 +246,7 @@ describe('requests', function () {
done();
return;
}
var response;
function str2ab(str) {