2

I need to setup a global interceptor for all my axios calls. I'm defining them inside vuex actions and I need that if there is a 429 status code, an action is called and then after that actions is made, a retry with the original request is made. I'm learning about interceptors but I don't know how to properly setup it,and if it will work outside the export default. Can anyone help me?

axios.interceptors.use( (response) => {
// if no status error code is returned get the response
  return response
}, (error) => {
  console.log(error)
  // here I need to retry the ajax call after that my loadProxy action is made and a 429 status code is sent from the server
  return Promise.reject(error);
})

export default new Vuex.Store({
 actions: {
  loadProxy({ commit }) {
  // here I have an axios get request to fetch a proxy from an API 
  },
  fetchData({ commit, state }) {
  // here I fetch the data to use in my app, sometimes due to many requests I need to refresh the proxy ip to let the app continue working
  }
 }
})
nukiko12
  • 129
  • 1
  • 1
  • 10

2 Answers2

10

The response object in Axios' interceptor contains a config object. (See here)

You can use that to re-initiate the request with the original configuration.

An example:

axios.interceptors.response.use((response) => {
    return response;
}, (error) => {
    if (error.response.status === 429) {
        // If the error has status code 429, retry the request
        return axios.request(error.config);
    }
    return Promise.reject(error);
});

To use a Vuex action inside the interceptor callback, you can first define the store as a variable, then call the dispatch function inside the callback. Like this:

const store = new Vuex.Store({
   // define store...
})

axios.interceptors.response.use((response) => {
    return response;
}, (error) => {
    if (error.response.status === 429) {
        store.dispatch("YOUR_ACTION");
        return axios.request(error.config);
    }
    return Promise.reject(error);
});

export default store;
hawschiat
  • 306
  • 1
  • 5
  • ok, seems a nice solution need to test also this. Before retry the request, how I can call a vuex action, will this possible with my code? I'm actually calling the interceptor before the `new Vuex({})` so I'm not sure if it work – nukiko12 Aug 25 '20 at 18:08
  • I want to setup the interceptor before the `Vuex` instance, inside the interceptor I want to call a later defined async vuex action that will be fired before the request is retried – nukiko12 Aug 25 '20 at 18:24
  • At the moment I already export my vuex instance in this way `export default new Vuex.Store({})` I'm worried that if I modify it the app will break up – nukiko12 Aug 25 '20 at 18:28
  • Ok, need to try, I hope that it will not break all the logics, I'm importing the store into the `main.js` file using `import store form '../store'` – nukiko12 Aug 25 '20 at 18:34
  • I get this error from webpack `error 'config' is not defined` this is related to the interceptor :( – nukiko12 Aug 25 '20 at 18:39
  • 1
    @nukiko12 sorry I made a mistake, the status code should be obtained from **error.response.status** instead of error.status and config should be obtained from **error.config**. You can refer to the documentation [here](https://github.com/axios/axios#handling-errors). I have corrected my answers above. – hawschiat Aug 25 '20 at 18:56
  • Great, many Thanks! I knew about `error.config`, but didn't know if `axios.request()` would deal with the config object automatically. I didn't want to do it manually in case axios changes the structure in future version. – KeitelDOG May 30 '22 at 18:22
4

You could have a experiment with axios-retry, there is a option

retryCondition: A callback to further control if a request should be retried

import axiosRetry from "axios-retry"

// ...

// intercept
axiosRetry(axios, {
  retries: 3,
  retryCondition: (error) => {
    return error.response.status === 429
  },
})

hgb123
  • 13,869
  • 3
  • 20
  • 38
  • If I understand this will replace the `axios.interceptor.use` right? I can also call a vuex action inside it? – nukiko12 Aug 25 '20 at 18:04
  • @nukiko12 yes, and you should be able to call vuex action inside that – hgb123 Aug 25 '20 at 18:07
  • I need to try, I want to define the retry before the vuex instance is created this is why I'm not sure if it can work – nukiko12 Aug 25 '20 at 18:12