Угловой обратный вызов AngularJS - $http не работает, даже если ответ об ошибке возвращается из веб-интерфейса API

Я вызываю метод с сервера, который возвращает ответ об ошибке вроде (ошибки 400 и 500), но мой обратный вызов с ошибкой AngularJS не вызывается, и всегда обратный вызов успеха вызывается, хотя мой код состояния содержит 400 или 500. Может кто-нибудь, пожалуйста, скажите, что я делаю неправильно? Ниже приведен код angular и WebAPI:

Код AngularJS:

$http.get("/api/employee")
    .success(function (data, status, headers, config) {
        console.log(data);
        return data;
    }).error(function (data, status, headers, config) {
        alert("error");
        return status;
});

Код веб-интерфейса:

public HttpResponseMessage Get(EmployeeModel employee)
{
     if (!ModelState.IsValid)
     {
         return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
     }
     //some other code
}

Ответ 1

Проблема заключается в наличии перехватчика, который неправильно передает ошибку.

Когда вызывается responseError перехватчика, он должен распространять исключение в стеке вызовов, поэтому следующие вызовы функций/обратные вызовы будут знать, что ошибка не срабатывает, а не удачный ответ.

$httpProvider.interceptors.push(function ($q, $rootScope) {

        return {
            request: function (config) {
                //the same config / modified config / a new config needs to be returned.
                return config;
            },
            requestError: function (rejection) {
                return $q.reject(rejection);
            },
            response: function (response) {
                //the same response/modified/or a new one need to be returned.
                return response;
            },
            responseError: function (rejection) {
                return $q.reject(rejection);
            }
        };
    });

Ответ 2

У меня была такая же проблема, и я все еще сам это понял, но я определил возможную проблему.

Обратный вызов .error() может быть предотвращен с помощью HTTP-ответчика-перехватчика (зарегистрированного путем добавления в массив $httpProvider.interceptors).

Я использовал модуль для добавления перехватчиков, и поэтому я удалил это и написал материал вручную.

Ответ 3

Мне никогда не повезло с параметрами .success и .error и закончил тем, что использовал .then для всего и еще не имел проблемы. Я должен также указать, что вы не можете вернуть ценности из обещания, как вы пытаетесь сделать. Вы должны объявить переменную с var перед вводом обещания или назначить новую переменную $scope в рамках обещания.

Итак, с этими изменениями ваш код будет выглядеть так:

var employees = $http({method:'GET', url:'/api/employee');
employees.then(function(data){
    $scope.employeeData = data;
}, function(data){
    //do error handling here
});

Кроме того, иногда может быть полезно централизованный метод обработки ошибок, и это можно сделать с помощью httpInterceptor (как описано здесь: Обрабатывать HTTP 302 ответ от прокси-сервера в angularjs). Это позволит вам полностью удалить вторую функцию в. Then, если не будет никакой другой обработки ошибок, что позволит сохранить код и пропускную способность.

Ответ 4

Я создал перехватчик для захвата задержки каждого HTTP-запроса и столкнулся с той же проблемой. Решение было очень простым. Просто замените: ответ возврата с return $q.reject(response);. Пример:

SCM.service('httpService', function($q) {
    this.request = function(config) {
        if (angular.isObject(config)) {
            config.delay = new Date().getTime();
        }
        return config;
    };
    this.requestError = function(config) {
        if (angular.isObject(config)) {
            config.delay = new Date().getTime();
        }
        return $q.reject(config);
    };
    this.response = function(response) {
        if (angular.isObject(response.config)) {
            response.config.delay = new Date().getTime() - response.config.delay;
        }
        return response;
    };
    this.responseError = function(response) {
        if (angular.isObject(response.config)) {
            response.config.delay = new Date().getTime() - response.config.delay;
        }
        return $q.reject(response);
    };
});

SCM.config(function($httpProvider) {
    $httpProvider.interceptors.push('httpService');
});