Retrofit重试请求回调问题:全局捕获状态码后原始回调未触发
解决拦截器重试后原始Callback未触发的问题
嘿,我之前也踩过这个一模一样的坑!这种情况几乎都是因为你的拦截器在完成重试请求后,没有把结果正确传递回原始的请求Promise链,导致原始的.then()/.catch()或者async/await的后续逻辑完全收不到信号。下面给你几个关键的修复点:
必须返回重试请求的Promise
这是最核心的一点。不管你用的是Axios、Fetch还是自定义的请求库,拦截器的错误处理函数不能只执行重试请求就完事,一定要return这个重试请求的Promise,让它成为原始请求链的一部分。比如Axios的例子:axios.interceptors.response.use( (response) => response, // 正常响应直接返回给原始链 async (error) => { const originalRequest = error.config; // 假设我们捕获401状态码并重试 if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; // 加个标记防止无限重试 // 先执行你的指定操作,比如刷新token await refreshAuthToken(); // 关键:返回重试后的请求Promise,把结果递回原始callback return axios(originalRequest); } // 如果不满足重试条件,把错误抛回原始链 return Promise.reject(error); } );要是不
return这个重试请求,原始的Promise就会卡在拦截器这里,永远触发不了后续的回调。避免覆盖原始请求的回调钩子
有些时候我们会不小心修改originalRequest上的then/catch绑定,导致原始的callback被覆盖。这种情况要确保你只在拦截器里添加重试逻辑,不要去篡改原始请求自带的回调处理。自定义请求库的通用逻辑
如果你是自己写的拦截器框架,核心思路还是一样:让拦截器的处理函数返回一个Promise,要么是正常响应,要么是重试后的请求Promise。比如基于Fetch的封装:const enhancedFetch = async (url, options = {}) => { let response = await fetch(url, options); // 捕获目标状态码 if (response.status === 401 && !options._retry) { options._retry = true; // 执行指定操作,比如更新请求头里的token options.headers = { ...options.headers, Authorization: `Bearer ${newToken}` }; // 返回重试请求,让原始调用者拿到结果 return enhancedFetch(url, options); } return response; };这样你调用
enhancedFetch(...).then(res => { /* 这里就能触发原始callback了 */ })就完全正常了。
简单来说,就是要让拦截器成为请求Promise链的一环,而不是一个独立的分支——重试后的结果必须沿着链传递回去,原始的callback才能感知到请求完成。
内容的提问来源于stack exchange,提问作者Lena Bru
相关产品推荐
相关产品推荐

