Axios interceptor retry http request when status is 200 and data is empty

陌路散爱 提交于 2019-12-13 08:27:49

问题


I am short polling an endpoint until some data is ready i would like to retry the request up to 10 times.

When the data is not ready i recieve a 200 with an empty array.

When the data is ready i recieve a 200 with a non-empty array.

I use the following libraries https://github.com/axios/axios https://github.com/softonic/axios-retry

 try {

   const axiosInstance = axios.create();

   axiosInstance.interceptors.response.use((response) => {

     if (response.data.metrics.length === 0) {
       const error = new Error("Metrics Not Ready");
       return Promise.reject(error);

     }
     return response;
   }, (error) => {
     return Promise.reject(error);
   });

   axiosRetry(axiosInstance, {
     retries: 10,
     retryCondition: (error) => {
       console.log("RETRY CONDITION", error);
     },
   });

   const metrics = await axiosInstance(options);

 } catch (error) {
   console.log(error);
 }

I have created an axios interceptor to check the length of the array if its 0 i am throwing an error. However this does not get caught by axiosRetry which at this point i want to retry the request. Instead it is being caught in the try catch block and ends.


回答1:


You don't need axios-retry, all you need is axios and its response interceptor, with following steps:

  1. Check whether data is empty. If yes, throw an axios.Cancel error. This would cancel the request, invoking error handler instead of success handler.
  2. In the error handler, re-send the HTTP request if we haven't exceeded the maximum retry number (in your case, it is 10).
  3. Keep running step 1 and 2 until we get data or have retried 10 times.

The code would look like below:

const axios = require('axios');

const MAX_RETRY = 10;
let currentRetry = 0;

function successHandler() {
  console.log('Data is Ready');
}

function errorHandler() {
  if (currentRetry < MAX_RETRY) {
    currentRetry++;
    console.log('Retrying...');
    sendWithRetry();
  } else {
    console.log('Retried several times but still failed');
  }
}

function sendWithRetry() {
  axios.get('http://example.com')
    .then(successHandler).catch(errorHandler);
}

axios.interceptors.response.use(function (response) {
  if (response.data.metrics.length) {
    throw new axios.Cancel('Operation canceled by the user.');
  } else {
    return response;
  }
}, function (error) {
  return Promise.reject(error);
});

sendWithRetry();

For axios-retry, unfortunately you cannot retry HTTP request when response status is 200 OK, as axios-retry uses axios.interceptors.response.use but does nothing for "successful response".

Here is the corresponding code in axios-retry's source file es/index.js. You can see that the interceptor of successful response is null:

export default function axiosRetry(axios, defaultOptions) {
  axios.interceptors.request.use(config => {
    const currentState = getCurrentState(config);
    currentState.lastRequestTime = Date.now();
    return config;
  });

  axios.interceptors.response.use(null, error => {
    const config = error.config;

    // If we have no information to retry the request
    if (!config) {
      return Promise.reject(error);
    }
    ....


来源:https://stackoverflow.com/questions/55865067/axios-interceptor-retry-http-request-when-status-is-200-and-data-is-empty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!