Axios 拦截器从 Vue.js 中的调用 Promise 中窃取 catch() 路径,破坏下游错误处理 [英] Axios interceptor steals catch() path from the calling Promise in Vue.js, breaking down-stream error handling

查看:54
本文介绍了Axios 拦截器从 Vue.js 中的调用 Promise 中窃取 catch() 路径,破坏下游错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 axios 中拦截受保护路由的 401 错误,但我的拦截器似乎从返回错误的 所有 HTTP 请求中窃取"了 catch() 链,并且丢失了它们包含的错误负载(UI 用于显示错误类型).这打破了所有使用 Vuex 动作登录、注册等的下游组件方法代码.

I am trying to intercept 401 errors in axios for protected routes, but my interceptor seems to 'steal' the catch() chain away from all HTTP requests that return an error, as well as losing the error payload they contain (which the UI uses to display the type of error). This breaks all the down-stream component methods code are using Vuex actions to login, register, etc.

一个可能的相关症状是我似乎无法将真实"引用传递给 currentRoute 对象来检查受保护状态的元属性.相反,我必须使用 ._value. 来获取路由的元属性的值.

A possible related symptom is that I don't seem to be able to pass a 'real' reference to the currentRoute object to check the meta attribute for protected status. Instead I have to use ._value. to get at the values of the route's meta property.

ma​​in.js

createApp(App)
    .use(store)
    .use(router)
    .provide('GStore', GStore)
    .mount('#app')

router.js

import registerInterceptor from '@/router/interceptor'
...
registerInterceptor(router)
export default router

interceptor.js

import axios from 'axios'
import store from '@/store/index'
export default (router) => {
  axios.interceptors.response.use(response => {
    return response;
  }, (error) => {
    let requiresAuth=router.currentRoute._value.meta.requiresAuth
    if (error.response.status === 401 && requiresAuth) {
        console.log('token expired',error.response)
        store.dispatch('logout')
    }
    return error
  });
}

LoginUser.js

methods: {
    login() {
      this.$store
        .dispatch('login', {
          username: this.username,
          password: this.password
        })
        .then(() => {
          //NOTE: this does not return an error if login fails because the axios interceptor.js changes the code path to only run through this `then` fork, but this STINKS
          if (this.$store.getters.loggedIn) {
            this.$router.push({name: 'EventList'})
          } else {
            this.error ='No active account found with the given credentials.'
          }
        })
      .catch(() => {
        console.log('this is never called UNLESS I remove `registerInterceptor(router)` from the router.js')
      })
    }
  }

推荐答案

问题是你的拦截器只是返回了error(有效地吞下了它),但它需要是一个Promise 用于 .then/.catch 链接.即拦截器需要返回Promise.resolvePromise.reject中的结果:

The problem is your interceptor is simply returning error (effectively swallowing it), but it needs to be a Promise for the .then/.catch chaining. That is, the interceptor needs to return the result in Promise.resolve or Promise.reject:

axios.interceptors.response.use(response => {
  return response;
}, (error) => {
  let requiresAuth = /*...*/
  if (error.response.status === 401 && requiresAuth) {
      //...

      // ignore error?
      return Promise.resolve();
  }
  return Promise.reject(error);
});

这篇关于Axios 拦截器从 Vue.js 中的调用 Promise 中窃取 catch() 路径,破坏下游错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆