javascriptreactjsreact-nativeaxios

Can I prevent Axios from making more than 1 total requests if that first request fails with 401?


My Axios instance has a response interceptor which emits an event if the response is 401 status code, and then I have a listener that executes a function, however my problem is that there are situations where multiple requests are being sent and my listener executes the function more than 1 times because I get multiple 401s in a row.

I'm trying to figure out if there's a clean way to make sure that Axios stops making requests after the first 401 status code and then resume after my listener function has finished executing.

My interceptor's error handler looks like this:

async (err) => {
            if (err.response.status === 401) Doorman.lock();

            return Promise.reject(err);
}

Solution

  • A possible approach can be to use lock (isLocked) and a queue (requestQueue) to block and queue requests after a 401 error, then retry them once unlocked.

    import axios from 'axios';
    
    let isLocked = false;
    let requestQueue = [];
    
    const api = axios.create();
    
    api.interceptors.request.use((config) => {
      if (isLocked) {
        return new Promise((resolve, reject) => {
          requestQueue.push({ config, resolve, reject });
        });
      }
      return config;
    });
    
    api.interceptors.response.use(
      (response) => response,
      async (error) => {
        if (error.response?.status === 401) {
          if (!isLocked) {
            isLocked = true;
            await Doorman.lock();
            isLocked = false;
            processQueue();
          }
          return Promise.reject(error);
        }
        return Promise.reject(error);
      }
    );
    
    function processQueue() {
      requestQueue.forEach(({ config, resolve, reject }) => {
        api.request(config)
          .then(resolve)
          .catch(reject);
      });
      requestQueue = [];
    }