我有一个基于组件的Angular应用程序,其中各个组件加载它们各自的数据。发生错误时,我通常希望组件显示错误消息。
但是,在某些情况下,我希望组件忽略错误,并将其留给一些全局错误处理机制来捕获它。
拦截器:
angular.module("...").factory("httpInterceptor", function($q) {
return {
responseError: function(response) {
// (1)
return $q.reject("I AM CALLED FIRST")
}
})
Serivce:
angular.module("...").service("myService", function($http){
return {
fetchData: function(){
return $http.get("...")
}
}
})
控制器:
angular.module("...").controller("MyController", function(myService){
myService.fetchData()
.then(function(){ ... })
.catch(function() {
// (2)
//I AM CALLED LAST
})
})
在大多数情况下,我希望在控制器中处理错误(在第(2)点)。如果控制器决定忽略错误(省略catch),则仍然可以在拦截器中捕获错误。
问题是拦截器不知道控制器是否打算捕获错误,因为它是在控制器之前调用的。因此拦截器不知道它是否应该显示错误(我不想要全局和本地错误消息)。
如何捕获控制器忽略的http错误?
答案 0 :(得分:7)
由于承诺不知道派生承诺的事情,似乎没有办法让它美丽的$ http,拦截器和承诺。
但如果你需要的话,这就是丑陋的方式:
$httpProvider.interceptors.push(['$q', '$timeout',
function ($q, $timeout) {
return {
responseError: function (response) {
$timeout(function () {
if (response.errorHandled) {
return;
}
// global AJAX error handling
}, 0);
return $q.reject(response);
}
};
}
]);
然后在.catch()
中的某个地方:
.catch(function(response){response.errorHandled = true;})
(我想我以前在SO上看过这样的答案,但是我找不到它。)
答案 1 :(得分:0)
如果你不想在控制器中处理,你可以抛出错误并让$ exceptionHandler来处理它。 你可以在配置阶段创建一个通用的错误处理程序:
$provide.decorator('$exceptionHandler', extendExceptionHandler);
答案 2 :(得分:0)
有点hacky但有一种方法可以为失败的$ http请求添加全局回退错误处理程序,但不指定errorCallback。
基本上,你装饰了$ http服务,以便在$ http请求失败且未指定errorCallback时触发'unhandledHttpError'事件。
这将触发'unhandledHttpError'事件:
$http.get('/invalid/url').then(function() {
//success handler
});
这不会触发'unhandledHttpError'事件:
$http.get('/invalid/url').then(function() {
//success handler
}, function() {
//error handler
});
处理'unhandledHttpError'事件:
$rootScope.$on('unhandledHttpError', function(event, response) {...});
以下是一个工作示例:https://jsfiddle.net/45w6o79p/27/
请参阅小提琴中的'myConfig'方法,您需要将$ http装饰代码粘贴到您的应用中以添加'unhandledHttpError'事件。