fix(interceptor): handle the error in the same interceptor (#6269)

* fix(interceptor): handle the error in the same interceptor

* fix(interceptor): pass the config and data in promise chain

* fix(interceptor): filter out unexpected config and data in promise chain

---------

Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
Tackoil 2026-01-09 03:11:34 +08:00 committed by GitHub
parent 7373fbff24
commit 5945e40bb1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 80 additions and 2 deletions

View File

@ -159,8 +159,13 @@ class Axios {
promise = Promise.resolve(config);
let prevResult = config;
while (i < len) {
promise = promise.then(chain[i++], chain[i++]);
promise = promise
.then(chain[i++])
.then(result => { prevResult = result !== undefined ? result : prevResult })
.catch(chain[i++])
.then(() => prevResult);
}
return promise;
@ -191,7 +196,7 @@ class Axios {
len = responseInterceptorChain.length;
while (i < len) {
promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);
promise = promise.then(responseInterceptorChain[i++]).catch(responseInterceptorChain[i++]);
}
return promise;

View File

@ -599,4 +599,77 @@ describe('interceptors', function () {
expect(instance.interceptors.response.handlers.length).toBe(0);
});
it('should handler the error in the same request interceptors', function (done) {
const rejectedSpy1 = jasmine.createSpy('rejectedSpy1');
const rejectedSpy2 = jasmine.createSpy('rejectedSpy2');
const error1 = new Error('deadly error 1');
const error2 = new Error('deadly error 2');
axios.interceptors.request.use(function () {
throw error1;
}, rejectedSpy1);
axios.interceptors.request.use(function () {
throw error2;
}, rejectedSpy2);
axios('/foo').catch();
getAjaxRequest().then(function () {
expect(rejectedSpy1).toHaveBeenCalledWith(error1);
expect(rejectedSpy2).toHaveBeenCalledWith(error2);
done();
});
});
it('should handle the error in the same response interceptors', function (done) {
const rejectedSpy1 = jasmine.createSpy('rejectedSpy1');
const rejectedSpy2 = jasmine.createSpy('rejectedSpy2');
const error1 = new Error('deadly error 1');
const error2 = new Error('deadly error 2');
axios.interceptors.response.use(function () {
throw error1;
}, rejectedSpy1);
axios.interceptors.response.use(function () {
throw error2;
}, rejectedSpy2);
axios('/foo');
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK'
});
setTimeout(function () {
expect(rejectedSpy1).toHaveBeenCalledWith(error1);
expect(rejectedSpy2).toHaveBeenCalledWith(error2);
done();
}, 100);
});
});
it('should skip the modification of config in the interceptors throwing error', function (done) {
const rejectedSpy = jasmine.createSpy('rejectedSpy');
const error = new Error('deadly error');
axios.interceptors.request.use(function (config) {
config.headers.test = 'added by interceptor';
return config;
});
axios.interceptors.request.use(function () {
throw error;
}, rejectedSpy);
axios('/foo').catch();
getAjaxRequest().then(function (request) {
expect(rejectedSpy).toHaveBeenCalledWith(error);
expect(request.requestHeaders.test).toBe('added by interceptor');
done();
});
});
});