Axios 拦截器从 Vue.js 中的调用 Promise 窃取 catch() 路径,破坏下游错误处理

Axios interceptor steals catch() path from the calling Promise in Vue.js, breaking down-stream error handling

我正在尝试拦截受保护路由的 axios 中的 401 错误,但我的拦截器似乎 'steal' catch() 链远离 all HTTP 请求 return 一个错误,以及丢失它们包含的错误负载(UI 用来显示错误类型)。这打破了所有下游组件方法代码使用 Vuex 操作来登录、注册等。

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

的值

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

问题是您的拦截器只是 returning error(有效地吞噬了它),但对于 .then/[= 它需要是 Promise 14=] 链接。即拦截器需要return结果在Promise.resolvePromise.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);
});