I am using an Axios interceptor (in React) to retry on 401 (when my access token expires). I want to limit to one retry but for some reason I'm unable to read the retried property I am defining.
This is the code I am using in the interceptor.
const responseIntercept = axios.interceptors.response.use(
(response) => response,
async (error) => {
const prevRequest = error?.config;
console.log(prevRequest);
console.log(prevRequest.retried);
if (error?.response?.status === 401 && !prevRequest?.retried) {
await new Promise(r => setTimeout(r, 1500)); // only here to delay the infinite retries
prevRequest.retried = true;
// log here returns true
const newAccessToken = await refresh();
prevRequest.headers['Authorization'] = newAccessToken;
return axios(prevRequest);
}
return Promise.reject(error);
}
);
For some reason, logging of prevRequest shows an object with the property retried, but the second log of .retried always logs 'undefined'. I assume this is the problem but I have no idea why I can see the property set but can't access it.
If I log prevRequest after adding the property, it does return true.
CodePudding user response:
I have been there recently, I used headers instead of modifying config.
const NO_RETRY_HEADER = 'x-no-retry'
const responseIntercept = axios.interceptors.response.use(undefined, async (error) => {
if (!axios.isCancel(error) && axios.isAxiosError(error) && error.response.status === 401) {
if (error.config.headers && error.config.headers[NO_RETRY_HEADER]) {
return Promise.reject(error)
}
error.config.headers ||= {}
error.config.headers[NO_RETRY_HEADER] = 'true' // string val only
const newAccessToken = await refresh()
error.config.headers['Authorization'] = newAccessToken
return axios(error.config)
}
return Promise.reject(error)
})