vue-resource:截获ajax错误时捕获“未捕获(承诺)”

ssc*_*ep3 5 javascript interceptor promise vue.js vue-resource

vue-resource用来从服务器获取数据。用户需要具有JWT令牌才能获取正确的数据。如果令牌无效或已过期,则返回401状态。如果用户尝试访问禁止页面,则返回403。

我想捕获这些错误并适当地(全局)处理它们。这意味着,呼叫应完全由拦截器处理(如果为401、403)。

如何防止浏览器消息“未捕获(承诺)”并创建一些全局错误处理?我不想在每个电话上都有本地错误处理程序。

我有以下拦截器:

Vue.http.interceptors.push(function (request, next) {
    request.headers.set('Authorization', Auth.getAuthHeader());

    next(function (response) {
        if (response.status === 401 || response.status === 403) {
            console.log('You are not logged in or do not have the rights to access this site.');
        }
    });
});
Run Code Online (Sandbox Code Playgroud)

Vue中的以下调用methods

methods: {
    user: function () {
        this.$http.get('http://localhost:8080/auth/user').then(function (response) {
            console.log(response);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

Ada*_*eis 4

这有点进退两难,不是吗?您不希望未处理的承诺拒绝被吞没,因为这意味着您的应用程序可能无法运行,并且您不会知道原因,并且永远不会得到发生错误的报告。

另一方面,为.catch()应用程序中的每个语句使用完全相同的错误处理机制是愚蠢的,因此实现全局错误处理程序绝对是正确的方法。

问题是,在大多数情况下,您必须全局错误处理程序中重新抛出错误,因为否则您的应用程序会认为请求处理正常并将继续处理数据,而这些数据将不存在。

但这会导致出现错误的情况Uncaught (in promise),因为浏览器会认为您没有处理错误,而实际上您在全局错误处理程序中处理了错误。

为了解决这个问题,现在有一个onunhandledrejection事件,您可以使用它来防止浏览器记录这些错误,但您必须确保自己处理它们。

所以我们经常做的就是拥有自己的错误类,当抛出响应错误时,我们根据 HTTP 状态代码将错误转换为我们的错误类之一。

我们还向此错误附加一个属性,例如ignoreUnhandledRejection并将其设置为true。然后,您可以使用全局处理程序来过滤掉这些错误并忽略它们,因为您知道您已经在全局范围内处理了它们:

/**
 * Prevent logging already processed unhandled rejection in console
 */
window.addEventListener('unhandledrejection', event => {
  if (event.reason && event.reason.ignoreUnhandledRejection) {
    event.preventDefault();
  }
});
Run Code Online (Sandbox Code Playgroud)