Angular: обработчик по умолчанию для необработанных ошибок http
В моем приложении angularjs я определил обработчик по умолчанию для http-ошибок следующим образом:
myapp.config([ '$httpProvider', function($httpProvider) {
$httpProvider.responseInterceptors.push('errorInterceptor')
}])
где errorInterceptor
- это служба, отображающая некоторые сведения об ошибке в поле предупреждения в верхней части текущей страницы.
Теперь, когда я хочу обрабатывать определенную ошибку другим способом (скажем, запрос запускается в модальном режиме, и я хочу отображать предупреждение только в этом модальном, а не на уровне страницы):
$http.get('/my/request').then(success, specificErrorHandling)
Angular выполняет specificErrorHandling
, но все же запускает мой errorInterceptor
, поэтому моя ошибка сообщается дважды. Есть ли способ избежать этого?
В общем случае существует ли способ Angular обрабатывать только ошибки, которые не выполняются по цепочке promise
, так же, как обработчик ошибок верхнего уровня серверного приложения не должен обрабатывать исключения?
Изменить: По просьбе Beetroot-Beetroot в комментариях, вот код для моего перехватчика:
@app.factory 'errorInterceptor', [ '$q', 'alertsHandler',
($q, alertsHandler) ->
success = (response) ->
response
failure = (response) ->
alertsHandler.raise(response)
(promise) ->
promise.then success, failure
]
Ответы
Ответ 1
У нас есть что-то подобное.
Если мы обрабатываем ошибку http, мы передаем свойство по запросу errorHandled:true
$http({
method: 'GET',
url: '/my/url',
errorHandled:true
}).then(function(){ ... }, function(){ ... });
И затем в перехвате для responseError: function(rejection){ ... }
мы можем видеть, установлен ли этот флаг, смотря на rejection.config.errorHandled
, а если нет - тогда мы выходим в диалог toastr с ошибкой. код выглядит примерно так:
function ( rejection ) {
if ( !rejection.config.errorHandled && rejection.data.message ){
toastr.error(rejection.data.message, 'Error');
}
return $q.reject(rejection);
}
Вероятность того, что кто-то пишет "errorHandled: true" без добавления обработчика, является тонким. Шансы иметь 2 индикатора ошибок также тонкие, потому что мы привыкли к нему, но на самом деле 2 индикатора лучше, чем ни один.
Было бы здорово, если бы у нас было обещание запросить его, если у него есть обработчик ошибок или нет в цепочке then
, но мы ничего не смогли найти.
Ответ 2
Предполагая, что вы знаете, какие ошибки нужно подавлять, а какие нужно распространять. Кроме того, поскольку перехватчик Response является функцией, которая возвращает само обещание
Вы можете поймать ответ на случай сбоя и вместо того, чтобы распространять его в стек, вы можете вернуть что-то вроде пустого ответа.
Если вы посмотрите пример пример в документации angular для перехватчика
$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
return function(promise) {
return promise.then(function(response) {
// do something on success
}, function(response) {
// do something on error
if (canRecover(response)) {
return responseOrNewPromise; // This can suppress the error.
}
return $q.reject(response); // This propogates it.
});
}
});