Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reject from 'response' into 'responseError'

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?

like image 479
Rob Campion Avatar asked Feb 14 '14 11:02

Rob Campion


3 Answers

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
    }
});
like image 161
Rob Campion Avatar answered Nov 14 '22 06:11

Rob Campion


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

like image 22
Remco Vlierman Avatar answered Nov 14 '22 04:11

Remco Vlierman


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;
});
like image 1
doubletap Avatar answered Nov 14 '22 04:11

doubletap