Error status codes are not being caught

2019-06-27 10:48发布

问题:

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?

回答1:

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.



回答2:

There is a function to capture the response of the HTTP status in Angular. You can look to see how it is done here stack overflow http response



回答3:

You can use an interceptor.

Intercept requests before they are handed to the server and responses before they are handed over to the application code that initiated these requests

So, This will catch all response errors originating from $http which $resource.

$httpProvider.interceptors.push(function($q) {
     return {
        'responseError': function(response) {
          if (response.status == 400) {
            // Handle 400 error code
          }
          if (response.status == 503) {
            // Handle 503 error code
          }

          // Rejects the derived promise.
          return $q.reject(response);
        }
      };
    });