12

我正在从服务器调用一个方法,该方法返回一个错误响应,例如(400 和 500 错误),但我的 AngularJS 错误回调没有被调用,并且即使我的状态代码包含 400 或 500,也总是调用成功回调。有人可以告诉我我做错了什么吗?请参阅下面的角度和 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;
});

网页 API 代码:

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

3 回答 3

16

问题是有一个拦截器,它不能正确传播错误。

当调用拦截器的 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);
            }
        };
    });

马蒂亚斯提到的观点是正确的,但它缺少返回元素。因此,如果您只是在 responseError 中拒绝,它不起作用,您需要返回拒绝,以便通知以下元素。

于 2014-12-28T00:23:31.920 回答
3

我创建了一个拦截器来捕获每个 HTTP 请求的延迟并面临同样的问题。解决方案非常简单。只需替换:返回响应; 返回$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');
});
于 2014-10-16T07:29:05.557 回答
1

我从来没有遇到过 .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 来完成(详见:Handle HTTP 302 response from proxy in angularjs)。这样做将允许您完全删除 .then 中的第二个函数,如果没有其他错误处理需要完成,从而节省代码和带宽。

于 2014-01-07T15:57:21.573 回答