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.
        });
    }
});