I'm using $http
interceptors to capture all events following an ajax submission. For some reason, I am not able to throw a requestError
. I've set up a test app to try and call requestError
, but so far I can only get multiple responseErrors
.
From angularjs docs:
requestError: interceptor gets called when a previous interceptor threw an error or resolved with a rejection.
This is my test code.
.factory('httpInterceptor',['$q',function(q){
var interceptor = {};
var uniqueId = function uniqueId() {
return new Date().getTime().toString(16) + '.' + (Math.round(Math.random() * 100000)).toString(16);
};
interceptor.request = function(config){
config.id = uniqueId();
console.log('request ',config.id,config);
return config;
};
interceptor.response = function(response){
console.log('response',response);
return response;
};
interceptor.requestError = function(config){
console.log('requestError ',config.id,config);
return q.reject(config);
};
interceptor.responseError = function(response){
console.log('responseError ',response.config.id,response);
return q.reject(response);
};
return interceptor;
}])
.config(['$httpProvider',function($httpProvider) {
$httpProvider.interceptors.push('httpInterceptor');
}])
.controller('MainCtrl',['$http',function($http){
var mainCtrl = this;
mainCtrl.method = null;
mainCtrl.url = null;
var testHttp = function testHttp() {
$http({method:mainCtrl.method,url:mainCtrl.url}).then(
(response)=>{console.log('ok',response);},
(response)=>{console.log('reject',response);}
);
};
//api
mainCtrl.testHttp = testHttp;
}])
I've tried multiple ways of creating http errors, and every time only responseError
gets called. Things I've tried:
400
and 500
.sleep
random times, to get some later requests to respond with an error before earlier requests. Same resource, same server response.404
errors by requesting resources which don't exist.responseError -1
).SIMILAR QUESTIONS
1) This question seems to have the answer: When do functions request, requestError, response, responseError get invoked when intercepting HTTP request and response?
The key paragrapgh being:
A key point is that any of the above methods can return either an "normal" object/primitive or a promise that will resolve with an appropriate value. In the latter case, the next interceptor in the queue will wait until the returned promise is resolved or rejected.
but I think I'm doing what it stipulates, viz random sleep
by the server but no luck. I am getting reponseErrors
out of order from the request ie as soon as the server responds.
2) A similar question was asked about 1 year ago: Angular and Jasmine: How to test requestError / rejection in HTTP interceptor?
Unfortunately, it only provides an explanation for interceptors
. It does not answer my question.
I have tested in Chrome and Firefox. I hope you understand, I've done my best to find a solution to this, but I haven't come across a solution as yet.
This happens because the request isn't rejected at any point. It is supposed to be used like that:
app.factory('interceptor1', ['$q', function ($q) {
return {
request: function (config) {
console.log('request', config);
if (config.url === 'restricted')
return $q.reject({ error: 'restricted', config: config });
}
};
}]);
app.factory('interceptor2', ['$q', function ($q) {
return {
requestError: function (rejection) {
console.log('requestError', rejection);
if (rejection.error === 'restricted')
return angular.extend(rejection.config, { url: 'allowed' });
return $q.reject(rejection);
}
};
}]);
app.config(['$httpProvider',function($httpProvider) {
$httpProvider.interceptors.push('interceptor1');
$httpProvider.interceptors.push('interceptor2');
}]);
Notice that interceptors are supposed to work in stack (starting from transform*
hooks in $http
request), so the request can't be rejected and recovered within a single interceptor.