14

In my angularjs app, I defined a default handler for http errors this way:

myapp.config([ '$httpProvider', function($httpProvider) {
    $httpProvider.responseInterceptors.push('errorInterceptor')
}])

where errorInterceptor is a service that displays some details about the error in an alert field on the top of the current page.

Now, when I want to handle a specific error in a different way (say the query is triggered in a modal, and I want to display the alert only in this modal, and not at page level):

$http.get('/my/request').then(success, specificErrorHandling)

Angular does the specificErrorHandling but still triggers my errorInterceptor, so my error gets reported twice. Is there a way to avoid that?

More generically, is there an Angular way to handle only errors that aren't already taken care of along the promise chain, the same way the top-level error handler of a server app doesn't have to handle catched exceptions?

Edit: As requested by Beetroot-Beetroot in comments, here is the code for my interceptor:

@app.factory 'errorInterceptor', [ '$q', 'alertsHandler',
  ($q, alertsHandler) ->
    success = (response) ->
      response

    failure = (response) ->
        alertsHandler.raise(response)

    (promise) ->
      promise.then success, failure
]
3
  • Can you post a (simplified version of) errorInterceptor please. Commented Jun 23, 2013 at 11:55
  • I think showing the alerts from interceptor its a not so good idea, and I think there is a no way achieve that (may be I'm wrong) Commented Aug 11, 2014 at 11:04
  • What specifically is done with the error is not the important part. It's really about having a default error handling, so you don't have to implement a specific error handler for 100% of async calls, and being able to defuse it when you do implement a specific handling. Much like exceptions. Is there a better way to implement a default error handler than an interceptor? Commented Apr 9, 2015 at 16:15

2 Answers 2

5

We have something like that.

If we handle the http error, we pass a property on the request called errorHandled:true

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

And then in the intercept for responseError: function(rejection){ ... } we can see if this flag is set by looking at rejection.config.errorHandled and if not - then we pop a toastr dialog with the error. the code looks something like this

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

The chances of someone writing "errorHandled:true" without adding a handler are slim. The chances of having 2 error indicators are also slim because we got used to it - but actually 2 indicators are better than none..

It would be great if we had the promise to query it if it has an error handler or not down the then chain, but we couldn't find this anywhere.

Sign up to request clarification or add additional context in comments.

Comments

1

Assuming that you know which errors needs to be suppressed and which one need to be propagate. Also since the Response interceptor is a function that returns promise itself

You can catch the response for failure case and instead of propagating it up the stack you can return something such as empty response.

If you look at the sample example in angular documentation for interceptor

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

3 Comments

Thank you, but this global error handler is executed before all the others and knows what it leaves to the others. What I'm after is the other way around: executed after the others and handling only what they left.
So you are looking for a common error handler, which can handle all unhandled errors, that runs in the event the calling code does not handle it?
That's it, a default error handler for when no specific one is defined (sorry about the very late relpy, I had missed yours)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.