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.resolve
或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 中的 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.resolve
或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);
});