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

Posted

技术标签:

【中文标题】vue-resource:在拦截 ajax 错误时捕获“未捕获(在承诺中)”【英文标题】:vue-resource: catch "Uncaught (in promise)" when intercepting an ajax error 【发布时间】:2017-08-31 18:38:17 【问题描述】:

我正在使用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.');
        
    );
);

以及 Vue 中的以下调用 methods:

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

【问题讨论】:

看起来您已经在拦截器中处理错误响应。您不想向调用者隐藏失败的响应/承诺,否则看起来一切正常。我不会担心控制台错误,大多数用户不会看到它们 @Phil,感谢您的回复。当then() 中没有捕获到异常时,是否没有副作用?我通常会尽量防止浏览器错误(HTTP 错误除外)。 【参考方案1】:

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

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

【讨论】:

以上是关于vue-resource:在拦截 ajax 错误时捕获“未捕获(在承诺中)”的主要内容,如果未能解决你的问题,请参考以下文章

vue-resource 拦截器使用

fetch拦截器的实现

终于掉坑里了!!!vue-resource和jquery的ajax不一样

Vue-Resource 在 Ajax POST 调用中给出 TokenMismatchException

Vue如何mock数据模拟Ajax请求

Vue 资源拦截器刷新 JWT 令牌