Home > database >  Axios Retry Infinite Loop
Axios Retry Infinite Loop

Time:08-16

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.

console log

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)
})

  • Related