【问题标题】:Restangular - How to override Error InterceptorsRestangular - 如何覆盖错误拦截器
【发布时间】:2015-07-10 04:03:42
【问题描述】:

我正在使用 AngularJS v1.2.16Restangular 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);
        }
    );
}

我明白,我的“第二个”错误处理程序没有被调用,因为我在 ErrorInterceptor 上返回 false

但是我该如何解决这个问题?我的应用中有很多“REST 操作”,但其中只有少数,我想要在出现问题时自定义行为。

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

现在,是这样流动的:

  • ErrorInterceptor > 结束。

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

  • ErrorInterceptor > Especific_ErrorHandler(如果存在)> End。

也可以是这样的:

  • Especific_ErrorHandler(如果存在)> ErrorInterceptor > End。

任何一种方式都适合我。

参考资料:

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

提前致谢!

【问题讨论】:

    标签: angularjs restangular


    【解决方案1】:

    这是你的代码:

    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;
        }
    );
    

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

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

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

    在文档中,清理已完成,您可以看到 deferred.reject 被传递。 https://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;
        }
    );
    

    【讨论】:

      【解决方案2】:

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

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

      .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);
          }
        };
      }
      • 然后将该工厂注册到$httpProvider 拦截器

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

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

      我希望这会按预期工作。

      【讨论】:

      • 你好,谢谢你的回复,我不知道写这个评论是否违反规则..但无论如何......我明天或后天会仔细看看你的答案,我刚搬到一个新地方……但很高兴知道有办法解决这个问题。谢谢。
      猜你喜欢
      • 2014-05-29
      • 1970-01-01
      • 2016-01-13
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      • 2015-11-13
      • 2015-03-15
      • 1970-01-01
      相关资源
      最近更新 更多