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
]

person ejoubaud    schedule 23.06.2013    source источник
comment
Можете ли вы опубликовать (упрощенную версию) errorInterceptor, пожалуйста.   -  person Beetroot-Beetroot    schedule 23.06.2013
comment
Я думаю, что показывать оповещения от перехватчика - не очень хорошая идея, и я думаю, что этого никак не добиться (может быть, я ошибаюсь)   -  person Narek Mamikonyan    schedule 11.08.2014
comment
Что конкретно делается с ошибкой, не столь важно. На самом деле речь идет об обработке ошибок по умолчанию, поэтому вам не нужно реализовывать конкретный обработчик ошибок для 100% асинхронных вызовов и иметь возможность обезвредить его, когда вы реализуете конкретную обработку. Очень похоже на исключения. Есть ли лучший способ реализовать обработчик ошибок по умолчанию, чем перехватчик?   -  person ejoubaud    schedule 09.04.2015


Ответы (2)


У нас есть что-то подобное.

Если мы обрабатываем ошибку http, мы передаем свойство в запросе с именем errorHandled:true

$http({
    method: 'GET',
    url: '/my/url',
    errorHandled:true
}).then(function(){ ... }, function(){ ... });

И затем в перехвате для responseError: function(rejection){ ... } мы можем увидеть, установлен ли этот флаг, посмотрев на rejection.config.errorHandled, а если нет, то мы выскочим диалоговое окно с ошибкой. код выглядит примерно так

function ( rejection ) { 
    if ( !rejection.config.errorHandled && rejection.data.message ){
        toastr.error(rejection.data.message, 'Error');
    }
    return $q.reject(rejection); 
} 

Шансы того, что кто-то напишет «errorHandled:true» без добавления обработчика, невелики. Шансы иметь 2 индикатора ошибок также невелики, потому что мы к этому привыкли, но на самом деле 2 индикатора лучше, чем ничего.

Было бы здорово, если бы у нас было обещание запросить его, есть ли у него обработчик ошибок или нет ли он дальше по цепочке then, но мы нигде не смогли найти это.

person guy mograbi    schedule 08.04.2015

Предполагая, что вы знаете, какие ошибки нужно подавлять, а какие — распространять. Кроме того, поскольку перехватчик 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.
        });
    }
});
person Chandermani    schedule 23.06.2013
comment
Спасибо, но этот глобальный обработчик ошибок выполняется раньше всех остальных и знает, что оставляет остальным. То, что мне нужно, - это наоборот: выполняться после других и обрабатывать только то, что они оставили. - person ejoubaud; 26.06.2013
comment
Итак, вы ищете общий обработчик ошибок, который может обрабатывать все необработанные ошибки, который запускается в том случае, если вызывающий код не обрабатывает его? - person Chandermani; 26.06.2013
comment
Вот и все, обработчик ошибок по умолчанию, когда конкретный не определен (извините за очень поздний ответ, я пропустил ваш) - person ejoubaud; 09.04.2015