Reject from 'response' into 'responseError'
Asked Answered
H

3

14

Sometimes, the API I'm using will return 200 ok even though there has been an error. The response JSON object will look something like:

{
    error: true
}

I've built a $http response interceptor that simply checks for this error and rejects it. I want it to then jump into my responseError function:

$httpProvider.interceptors.push(function($q) {
    return {

        response: function (response) {

            if (response.data.error) {

                // There has been an error, reject this response
                return $q.reject(response);
            }

            return response;
        },

        responseError: function(rejection) {

            // Display an error message to the user
            ...

            return $q.reject(rejection);
        }
    }
});

Problem is, even after rejecting the response, my responseError function isn't called. It is called on 500 errors etc so I know it's working. I'd expect a rejection to do the same thing.

From the docs:

responseError: interceptor gets called when a previous interceptor threw an error or resolved with a rejection.

Any ideas on what's missing?

Horsy answered 14/2, 2014 at 11:29 Comment(1)
Looks like this isn't possible to do. To cut down on duplicate code, I simply declared the error handling function separately and reused it inside the response and responseError function:Horsy
H
7

Looks like this isn't possible to do. To cut down on duplicate code, simply declare the error handling function separately and reuse it inside the response and responseError functions.

$httpProvider.interceptors.push(function($q) {

    var handleError = function (rejection) { ... }

    return {

        response: function (response) {

            if (response.data.error) {
                return handleError(response);
            }

            return response;
        },

        responseError: handleError
    }
});
Horsy answered 17/2, 2014 at 11:29 Comment(1)
Sometimes the solution is more basic than you'd expect.Tanked
P
2

To add to this answer: rejecting the promise in the response interceptor DOES do something.

Although one would expect it to call the responseError in first glance, this would not make a lot of sense: the request is fulfilled with succes. But rejecting it in the response interceptor will make the caller of the promise go into error handling. So when doing this

$http.get('some_url')
.then(succes)
.catch(err)

Rejecting the promise will call the catch function. So you don't have you proper generic error handling, but your promise IS rejected, and that's useful :-)

Prebend answered 29/11, 2016 at 9:20 Comment(3)
btw, I don't think you should do displaying of error messages in your interceptor: create a separate service for that, and inject / call it in your controller in the catch() as described abovePrebend
You are saying that responseError gets called when there is an error/rejection on the request, not the response? You are right, this does make more sense. The docs site could use some work.Altimetry
@Altimetry yeah, took me some headache to figure this one out. So you do not use this for generic error handling or something like that, but you can use it do reject a http-promise based on the repsponse content this way. interesting stuff ;-)Prebend
R
1

Should you want to pass the http response to the responseError handler, you could do it like this:

$httpProvider.interceptors.push(function($q) {

    var self = {

        response: function (response) {

            if (response.data.error) {
                return self.responseError(response);
            }

            return response;
        },

        responseError: function(response) {
            // ... do things with the response
        }
    }
    return self;
});
Remonstrant answered 29/6, 2017 at 23:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.