Restangular - 如何覆盖错误拦截器

时间:2015-01-18 14:06:40

标签: angularjs restangular

我正在使用 AngularJS v1.2.16 Restangular v1.4.0 ,并且想知道是否可以覆盖ErrorInterceptor。如果有,怎么样?如果不是,我该如何解决?

我已经像这样配置了一个错误拦截器:

RestangularProvider.setErrorInterceptor(
    function ( response ) {
        if ( response.status == 401 ) {
        dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
            .result.then( function () {
                $location.path("/login");
            });
        }
        else {
            // Some other unknown Error.
            console.log( response );
            dialogs.error(response.statusText + " - Error " + response.status,
                "An unknown error has occurred.<br>Details: " + response.data);
        }
        // Stop the promise chain.
        return false;
    }
);

然后,在另一个地方,我进行了一次错误处理的POST调用。

function saveApple( apple ) {
    Restangular.all("apple/save").post( apple ).then(
        function ( response ) {
            console.log("Saved");
        },
        function ( response ) {
            // This is not being called.
            console.log("Error with status code", response.status);
        }
    );
}

据我所知,我的“第二个”错误处理程序未被调用,因为我正在false上返回ErrorInterceptor

但我怎么能解决这个问题呢?我的应用程序中有很多“REST操作”,只有少数几个,我想在出现问题时进行自定义行为。

到目前为止,我想到的唯一解决方法是使ErrorInterceptor返回true,并且对于每个其他REST操作,我复制粘贴相同的错误处理程序(更一般一)。但这将是我要做的最后一件事。

现在,这样流淌:

  • ErrorInterceptor&gt;端。

如果可能,我希望它是这样的:(仅针对特定方法 - 不是全部)。

  • ErrorInterceptor&gt; Especific_ErrorHandler(如果存在)&gt;端。

它也可以是这样的:

  • Especific_ErrorHandler(如果存在)&gt; ErrorInterceptor&gt;端。

无论哪种方式都适合我。

参考文献:

https://github.com/mgonto/restangular#seterrorinterceptor https://github.com/mgonto/restangular#how-can-i-handle-errors

提前致谢!

2 个答案:

答案 0 :(得分:15)

这是你的代码:

RestangularProvider.setErrorInterceptor(
    function ( response ) {
        if ( response.status == 401 ) {
        dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
            .result.then( function () {
                $location.path("/login");
            });
        }
        else {
            // Some other unknown Error.
            console.log( response );
            dialogs.error(response.statusText + " - Error " + response.status,
                "An unknown error has occurred.<br>Details: " + response.data);
        }
        // Stop the promise chain.
        return false;
    }
);

你为什么使用拦截器? - 因为你想要全面的对话框来显示错误信息。

停止承诺链,这是不好的做法吗?

我不知道。很多人使用错误回调;并且一个用于错误回调的用例是进行一些清理。如果你杀了承诺链,你如何确保清理完成?停止承诺链意味着您的错误回调,catch块和finally块将不会被调用。

在文档中,清理完成后,您可以看到传递了deferred.rejecthttps://github.com/mgonto/restangular#seterrorinterceptor 也许你误解了文档中的例子。

可能的解决方案#1

        // DON'T stop the promise chain.
        return true;

可能的解决方案#2

不要处理错误拦截器中的未知错误。

RestangularProvider.setErrorInterceptor(
    function ( response ) {
        if ( response.status == 401 ) {
            dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
                .result.then( function () {
                   $location.path("/login");
                });
            // Stop the promise chain.
            // all unauthorized access are handled the same.
            return false;
        }
        // Some other unknown Error.
        console.log( response );
        dialogs.error(response.statusText + " - Error " + response.status,
            "An unknown error has occurred.<br>Details: " + response.data);
        }
        // DON'T stop promise chain since error is not handled
        return true;
    }
);

可能的解决方案#3

停止承诺链时调用reject

RestangularProvider.setErrorInterceptor(
    function ( response, deferred, responseHandler ) {
        if ( response.status == 401 ) {
            dialogs.error("Unauthorized - Error 401", "You must be authenticated in order to access this content.")
                .result.then( function () {
                   // continue promise chain in this callback.
                   deferred.reject("unauthorized");
                   $location.path("/login");
                });
            // Stop the promise chain here
            // all unauthorized access are handled the same.
            return false;
        }
        // Some other unknown Error.
        console.log( response );
        dialogs.error(response.statusText + " - Error " + response.status,
            "An unknown error has occurred.<br>Details: " + response.data);
        }
        // DON'T stop promise chain since error is not handled
        return true;
    }
);

答案 1 :(得分:2)

是的,您可以创建自定义httpErrorHandler

  • 首先,您需要创建一个.factory,让我们称之为httpErrorHandler

&#13;
&#13;
.factory('httpErrorHandler', function ($rootScope) {
  return {
    'error': function (rejection) {
      if (rejection.status === 422) {
        $rootScope.$broadcast('422_error', rejection.data);
      } else if (rejection.status === 403) {
        $rootScope.$broadcast('403_error', rejection.data);
      } else {
        $rootScope.$broadcast('unknown', rejection.data);
      }
      return $q.reject(rejection);
    }
  };
}
&#13;
&#13;
&#13;

  • 然后将该工厂注册到$httpProvider拦截器

&#13;
&#13;
.config(function ($httpProvider) {
  $httpProvider.interceptors.push('httpErrorHandler');
});
&#13;
&#13;
&#13;

然后在应用程序中的任何地方捕获$rootScope事件并处理它们,或者在拦截器中添加一些逻辑。

我希望这会按预期工作。