Search code examples
angularjsangular-resourceionic-v1

Error status codes are not being caught


I am trying to catch angular resource's HTTP error status code (!=200). My Service, where I have resources defined: (apiService.js)

.factory('ApiService', function($resource, $http, localStorageService, CONFIG) {

    var base_api_url = api_url = CONFIG.api_url, api_version_prefix = CONFIG.api_version_prefix;

    return {
        userDevices: $resource(api_url+'/requestRegistration/userDevices/:action', {}, {
            registerDevice: {
                method: 'POST',
                params: {
                   action: ''
                }
            },
            verify: {
                method: 'POST',
                params: {
                   action: 'verify'
                }
            },               
        }
    }
});

My controller's code:

.controller('LoginCtrl', function(CONFIG, $scope, $state, $ionicPlatform, $ionicPopup, ApiService) {


    $scope.data = {
        username: null
    };

    $scope.registerDevice = function() {
        if($scope.data.username) { 
            var authenticationResponse = ApiService.userDevices.registerDevice({
                username: $scope.data.username
            });

            authenticationResponse.$promise.then(function(result) {
                // this is always fired, even then response code is 400 or 503 :( I am not able to check response status code.
                console.log(result);
                console.log('success!');
            }, function(error){
                // this code is not being exectued even when response status code is different then 200
                // its never executed at all :(
                console.log('error!');
            });
        }
    };


});

When I send the request and I receive response code 400/503, I believe that function(error) code should be executed but it's not.

Instead, my code in $promise.then(function(result)(...) is executed and I am not able to detect a response HTTP status code.

So, my questions:

  1. Why isn't my error handling function being executed?
  2. How can I detect HTTP response status codes?

Solution

  • The first .catch is converting rejections to fulfilled. To prevent conversion, the .catch method needs to throw the error.

       authenticationResponse.$promise.catch(function(error){
            alert('catched error!!!');
            //throw to chain error
            throw error;
        }).then(function(result) {
            // this is always fired, even then response code is 400 or 503 :(
            console.log(result);
            console.log('success!');
            //return to chain data
            return result
        }, function(error){
            // This should be executed when status code is different then 200?
            // its never executed at all :(
            console.log('error!');
            //throw to chain rejection
            throw error;
        });
    

    When a function omits a return or throw statement, it returns undefined. The $q service creates a derived promise that resolves to undefined.


    Diagnosing ngResource Problems

    To diagnose problems with $resource methods, add a response interceptor:

    userDevices: $resource(api_url+'/requestRegistration/userDevices/:action', {}, {
            registerDevice: {
                method: 'POST',
                params: {
                   action: ''
                },
                interceptor: {
                    response: function (response) {
                        console.log("registerDevice success");
                        console.log(response.status);
                        return response;
                    },
                    errorResponse: function (errorResponse) {
                        console.log("registerDevice error");
                        console.log(errorResponse.status);
                        throw errorResponse;
                    }
                }
            },
            verify: {
                method: 'POST',
    

    The other thing to look for is other $http interceptors in the App converting responses by omitting a throw statement.