title: Axios Reponse Interceptor : unable to handle an expired refresh_token (401)
body: <p>I have the following interceptor on my axios reponse :</p>
  
  
  
  <pre class="lang-js prettyprint-override"><code>window.axios.interceptors.response.use(
    response =&gt; {
      return response;
    },
    error =&gt; {
      let errorResponse = error.response;
      if (errorResponse.status === 401 &amp;&amp; errorResponse.config &amp;&amp; !errorResponse.config.__isRetryRequest) {
        return this._getAuthToken()
          .then(response =&gt; {
            this.setToken(response.data.access_token, response.data.refresh_token);
            errorResponse.config.__isRetryRequest = true;
            errorResponse.config.headers['Authorization'] = 'Bearer ' + response.data.access_token;
            return window.axios(errorResponse.config);
          }).catch(error =&gt; {
            return Promise.reject(error);
          });
      }
      return Promise.reject(error);
    }
  );
  </code></pre>
  
  <p>The _getAuthToken method is :</p>
  
  <pre class="lang-js prettyprint-override"><code>_getAuthToken() {
      if (!this.authTokenRequest) {
          this.authTokenRequest = window.axios.post('/api/refresh_token', {
              'refresh_token': localStorage.getItem('refresh_token')
          });
          this.authTokenRequest.then(response =&gt; {
              this.authTokenRequest = null;
          }).catch(error =&gt; {
              this.authTokenRequest = null;
          });
      }
  
      return this.authTokenRequest;
  }
  </code></pre>
  
  <p>The code is heavily inspired by <a href="https://github.com/axios/axios/issues/266#issuecomment-335420598" rel="nofollow noreferrer">https://github.com/axios/axios/issues/266#issuecomment-335420598</a>.</p>
  
  <p>Summary : when the user makes a call to the API and if his access_token has expired (a 401 code is returned by the API) the app calls the /api/refresh_token endpoint to get a new access_token. If the refresh_token is still valid when making this call, everything works fine : I get a new access_token and a new refresh_token and the initial API call requested by the user is made again and returned correctly.</p>
  
  <p>The problem occurs when the refresh_token has also expired.<br>
  In that case, the call to /api/refresh_token returns a 401 and nothing happens. I tried several things but I'm unable to detect that in order to redirect the user to the login page of the app.<br>
  I found that in that case the if (!this.authTokenRequest) statement inside the _getAuthToken method returns a pending Promise that is never resolved. I don't understand why this is a Promise. In my opinion it should be null...</p>
  
  <p>I'm a newbie with Promises so I may be missing something !
  Thanks for any help !</p>
  
  <p><strong>EDIT :</strong></p>
  
  <p>I may have found a way much simpler to handle this : use axios.interceptors.response.eject() to disable the interceptor when I call the /api/refresh_token endpoint, and re-enable it after.</p>
  
  <p>The code :</p>
  
  <pre class="lang-js prettyprint-override"><code>createAxiosResponseInterceptor() {
          this.axiosResponseInterceptor = window.axios.interceptors.response.use(
              response =&gt; {
                  return response;
              },
              error =&gt; {
                  let errorResponse = error.response;
                  if (errorResponse.status === 401) {
                      window.axios.interceptors.response.eject(this.axiosResponseInterceptor);
                      return window.axios.post('/api/refresh_token', {
                          'refresh_token': this._getToken('refresh_token')
                      }).then(response =&gt; {
                          this.setToken(response.data.access_token, response.data.refresh_token);
                          errorResponse.config.headers['Authorization'] = 'Bearer ' + response.data.access_token;
                          this.createAxiosResponseInterceptor();
                          return window.axios(errorResponse.config);
                      }).catch(error =&gt; {
                          this.destroyToken();
                          this.createAxiosResponseInterceptor();
                          this.router.push('/login');
                          return Promise.reject(error);
                      });
                  }
                  return Promise.reject(error);
              }
          );
      },
  </code></pre>
  
  <p>Does it looks good or bad ? Any advice or comment appreciated.  </p>