Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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 :-)

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;
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top