Axios 拦截器从 Vue.js 中的调用 Promise 中窃取 catch() 路径,破坏下游错误处理 [英] Axios interceptor steals catch() path from the calling Promise in Vue.js, breaking down-stream error handling
问题描述
我正在尝试在 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.
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')
})
}
}
推荐答案
问题是你的拦截器只是返回了error
(有效地吞下了它),但它需要是一个Promise
用于 .then
/.catch
链接.即拦截器需要返回Promise.resolve
或Promise.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屋!