softonic / axios-retry

Axios plugin that intercepts failed requests and retries them whenever possible
Other
1.9k stars 167 forks source link

Retry not working on HTTP 502 #262

Open aloysius-tim opened 10 months ago

aloysius-tim commented 10 months ago

Hi there,

After few months in production, just realized that some HTTP code are not retried as HTTP 502.

retryCondition is configured to return always TRUE. But its not retried and not getting any logs from onRetry.

I'm using the following versions: "axios": "^1.3.5" & "axios-retry": "^4.0.0"

Thank you guys for maintaining this great project ! :-)

Best, Tim

Alzanari commented 9 months ago

Hi,

I'm having a similar problems where retryCondition is configured to return always TRUE but it is ignored and the error propagates as if axios-retry is not even there.

although this behavior is not consistent and it does catch the error some times, (mostly ECONNREFUSED in my case).

I'm using the following versions: "axios": "^1.6.7" & "axios-retry": "^4.0.0".

i'm not sure how to go about diagnosing this issue but i hope you guys can reproduce and solve it.

best regards, Al

mindhells commented 9 months ago

Can you guys provide a minimum example reproducing the issue?

ThomasAriano commented 7 months ago

I am having a similar issue, v4.0.0 / axios 1.6.0.

I have setup retryCondition to always return true and have retries set to 4.

I have a request that returns 401 (intentionally). It always retries only 1 or 2 two times (seemingly inconsistently) and then returns the error. I am using CJS.

I downgraded to 3.9.1, and the issue resolved itself. EDIT: Issue persists.

const axiosRetry = require('axios-retry').default;
const axios = require('axios');

let axiosInstance = axios.create();
axiosRetry(axiosInstance, {
    retries: 0, // DO NOT RETRY BY DEFAULT
    onRetry: (retryCount, err, config) => {
        logger.info({ err, config }, `Retry attempt from  ${retryCount}`);
    },
});

const retryOptions = {
    retries: 4,
    retryDelay: retryCount => retryCount * 5000,
    retryCondition: async err => {
        console.log('ERR MESSAGE:', err?.message);
        return true;
    },
};

await axiosInstance({
    url: 'ENDPOINT_THAT_RETURNS_401',
    timeout: 45000,
    'axios-retry': retryOptions,
});

EDIT: I believe I've figured it out. If you have a timeout set in your request options (for example, 3000ms) that timeout seems to apply across all requests, instead of each request retry. So the reason my requests were inconsinstely failing was because sometimes they took 30 seconds to timeout, and would eat up most of my timeout. Here is a reproducible script:

const axios = require('axios');
const axiosRetry = require('axios-retry');

let axiosInstance = null;
const initAxios = () => {
    axiosInstance = axios.create();
    axiosRetry(axiosInstance, {
        retries: 0, // DO NOT RETRY BY DEFAULT
    });
};

const main = () => {
    initAxios();

    const options = {
        method: 'GET',
        url: 'https://httpbin.org/status/401,402,403,404,500,501',
        timeout: 3000,
        'axios-retry': {
            retries: 10,
            retryDelay: retryCount => retryCount * 100,
            retryCondition: err => true,
            onRetry: retryCount => {
                console.log('RETRYING', retryCount);
            },
        },
    };

    axiosInstance(options)
        .then(() => {
            console.log('Done');
        })
        .catch(error => {
            console.error('Error', error.message);
        });
};

main();

Which results in very confusing behavior:

node testAxiosRetry.js 

RETRYING 1
RETRYING 2
RETRYING 3
RETRYING 4
RETRYING 5
Error Request failed with status code 401

I would expect to see a timeout error (which is what actually happened) but instead we get back the last error we saw.

@mindhells Is this intended?

EDIT (last, hopefully): I should've RTFM. I just found shouldResetTimeout.

Obviously user error, but I'm going to leave this here in case it happens to someone else.