GwynBleidD
GwynBleidD

Reputation: 20569

Handling errors on 200 HTTP response using interceptors

I have service that integrates with external API. This API is inconsistent and it is unlikely to change.

Inside API there are 2 methods of reporting error, one is response with HTTP 500 code, other is normal 200 HTTP reponse, but with status in JSON set to "error".

Handling 500 error is working fine, I have just created interceptor (ngResource interceptor, not $http one) with responseError method that will display error message to user when there is any 500 response from API:

.factory('ApiErrorHandling', ['ngDialog', function(ngDialog) {
    return {
        responseError: function(response) {
            console.log(response);
            var error_dialog = ngDialog.open({
                template: '/api/error.html',
                className: 'error',
                preCloseCallback: function() {
                    if (response.data.status == 'fatal') {
                        window.location.href = '/';
                    } else if (response.data.status == 'error') {
                        var dialogs = ngDialog.getOpenDialogs();
                        for (var i in dialogs) {
                            var dialog = dialogs[i];
                            if (dialog != error_dialog.id) {
                                ngDialog.close(dialog);
                            }
                        }
                    }
                },
                data: {
                    code: response.data.code,
                    status: response.data.status,
                    message: response.data.message,
                    httpCode: response.status,
                }
            });
        },
    }
}])
.factory('ApiMethod', ['$resource', 'ApiErrorHandling', function($resource, ApiErrorHandling) {
    return $resource('/api/method/', {}, {
            query: {method:'POST', interceptor: ApiErrorHandling},
    });
}])

But I have problem with handling error responses with status. I don't want normal success callback (passed into method from resource instance) to be called when error occurs, I want one global error handler, but nothing I've tried so far worked. Each time response is passed into callback. I've tried so far:

Ideal solution will be when normal callback won't be called, but my responseError method from interceptor will be called instead.

Upvotes: 2

Views: 1854

Answers (2)

GwynBleidD
GwynBleidD

Reputation: 20569

I've found solution. I think is some bug in ngResource module.

When registered for callback like this:

ApiMethod.query({'get_parameter': 1}, {'post_json': 2}, function(result) {
    something...
});

Only solution to prevent calling callback is throwing error from ngResource interceptor. But when callback in registered in promise:

ApiMethod.query({'get_parameter': 1}, {'post_json': 2}).$promise.then(function(result) {
    something...
});

Calling callback can be prevented just by returning $q.reject from interceptor.

Rewriting all callback registering fixes the problem.

Upvotes: 1

georgeawg
georgeawg

Reputation: 48968

But I have problem with handling error responses with status. I don't want normal success callback (passed into method from resource instance) to be called when error occurs, I want one global error handler, but nothing I've tried so far worked. Each time response is passed into callback. I've tried so far:

returning $q.reject in response method from interceptor

To reject a response you don't like, use throw:

function inteceptor(httpPromise) {
    var newPromise = (httpPromise
        .then(function(response) {
                  if (dontLike) {
                      throw response;
                  } else {
                      return response;
              },
              function (eResponse) {
                  if (iLike) {
                      return eResponse;
                  } else {
                      throw eResponse;
                  };
              })
     );
     return newPromise;
};

To chain from your interceptor

var chainedPromise = (interceptor(httpPromise)
    .then (function (response) {
         //render data
         return response;
    }).catch (function (error) {
         console.log(error);
         throw error;
    })
);

Upvotes: 3

Related Questions