Axios拦截器禁用异常捕获问题:刷新JWT令牌后无法进入catch代码块
Axios拦截器刷新JWT后请求不进入catch块的排查与解决
1. 响应拦截器错误分支未正确抛出错误
这是最常见的问题:拦截器处理401刷新token时,若刷新失败或遇到非401错误,没有将错误重新抛出,导致Promise链无法进入rejected状态,catch块自然不会触发。
正确的拦截器写法:
axios.interceptors.response.use( response => response, async error => { const originalRequest = error.config; // 标记请求已重试,避免无限循环 if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; try { // 调用刷新token接口 const refreshRes = await axios.post('/refresh-token', { refreshToken: localStorage.getItem('refreshToken') }); // 更新本地token localStorage.setItem('accessToken', refreshRes.data.accessToken); // 重新发起原请求 return axios(originalRequest); } catch (refreshErr) { // 刷新失败必须抛出错误,否则catch块无法捕获 return Promise.reject(refreshErr); } } // 非401错误直接抛出 return Promise.reject(error); } );
核心:所有错误分支必须通过Promise.reject()传递错误,不能吞掉。
2. axios-auth-refresh配置未处理刷新失败场景
使用该包时,refreshAuthFunction必须在刷新失败时返回rejected Promise,否则包会默认认为刷新成功,不会将错误传递到业务代码的catch块。
正确配置示例:
import createAuthRefreshInterceptor from 'axios-auth-refresh'; const refreshAuthLogic = async failedRequest => { try { const res = await axios.post('/refresh-token', { refreshToken: localStorage.getItem('refreshToken') }); localStorage.setItem('accessToken', res.data.accessToken); // 更新原请求的Authorization头 failedRequest.response.config.headers['Authorization'] = `Bearer ${res.data.accessToken}`; return Promise.resolve(); } catch (err) { // 刷新失败返回rejected Promise return Promise.reject(err); } }; createAuthRefreshInterceptor(axios, refreshAuthLogic);
3. 全局拦截器吞掉了错误
检查项目中是否存在其他全局拦截器,错误分支只做了日志输出但未抛出错误:
// 错误示例:吞掉错误的拦截器 axios.interceptors.response.use( res => res, err => { console.error('请求错误:', err); // 缺少 return Promise.reject(err); } );
确保所有拦截器的错误分支都通过Promise.reject(err)传递错误。
4. 验证请求是否真的失败
有时候请求已成功重试,但业务代码误判为失败;或者后端返回非2xx的业务错误(如400),但拦截器未处理这类情况。可在拦截器中打印错误详情,确认错误类型和状态码,再针对性处理。
内容的提问来源于stack exchange,提问作者Anwar Javed
相关产品推荐
相关产品推荐

