vue-resource:catch" Uncaught(in promise)"在拦截ajax错误时

时间:2017-04-05 23:22:55

标签: javascript promise vue.js interceptor vue-resource

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

我想抓住这些错误并适当地(全局地)处理它们。这意味着调用应该由拦截器完全处理(如果是401,403)。

如何阻止浏览器消息" Uncaught(in promise)"并创建一些全局错误处理?我不想在每次通话时都有本地错误处理程序。

我有以下拦截器:

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

以下来自Vue methods的电话:

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

1 个答案:

答案 0 :(得分:1)

这是一个难题,不是吗。您不希望吞下未处理的承诺拒绝,因为这意味着您的应用程序可能无法运行,并且您将不知道为什么,并且永远也不会收到有关发生错误的报告。

另一方面,对应用程序中的每个.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();
  }
});