retry-axios
retry-axios copied to clipboard
I set retry 3 times,but only retry 1 times
raxConfig: {
retry: 3,
noResponseRetries: 5,
instance: http,
retryDelay: 100,
httpMethodsToRetry: ['GET', 'OPTIONS', 'POST'],
shouldResetTimeout: false,
onRetryAttempt: (err) => {
const cfg = rax.getConfig(err);
console.log(cfg.currentRetryAttempt);
}
}
Is the axios instance being shared? I ran into a similar issue and found that the retry counter is shared between multiple uses of a single instance.
Possibly related to #61
Greetings! Can you share a complete code example that does this? We have tests specifically covering number of retries, so an isolated example of how to break it would be super helpful.
@JustinBeckwith was that WRT my comment? I assumed #61 was well-known. Wanted to confirm before I spent time making a clear example.
Also, thank you for the awesome tool. I use it in every lambda project.
Hello @JustinBeckwith, thanks for the library.
Here is a reproducible demo for you: https://github.com/tomic-dvica-golf/retry-axios-demo/tree/master
just run yarn test. hope you find it useful!
Note that #61 was fixed, so this issue is probably also fixed.
Sweet. Could I trouble anyone to try it and take a look?
Hi @JustinBeckwith, I ran into the same issue where I have specified both retry count and noResponseRetries to 3.
I have debugged the "retry-axios" code and turns out that during the first initial request raxConfig received the correct value of httpMethodsToRetry & statusCodesToRetry i.e Array which I have passed from my code as config.
But when an error occurred for first time, The response interceptor is being called with correct raxConfig and in that shouldRetryRequest is called which returns true to retry the 1st attempt of the request.
Now, in this 1st attempt of retry, The response interceptor receives the incorrect raxConfig i.e the value of httpMethodsToRetry & statusCodesToRetry is Object this time but not Array therefore when normalizeArray is called from response interceptor it receives Object and return empty Array hence shouldRetryRequest function return false as the condition config.httpMethodsToRetry.indexOf(err.config.method.toUpperCase()) < 0
evaluates to true.
Please find the attached screenshots for a better understanding.
This is the Initial raxConfig when the first-time error occurred which in my case is timeout.
Now this is the raxConfig for 1st retry attempt and error occurred, Here you can clearly see the value of httpMethodsToRetry & statusCodesToRetry is Object this time but not Array.
therefore normalizeArray return empty Array
now for this error when shouldRetryRequest function called see the config now.
therefore config.httpMethodsToRetry.indexOf(err.config.method.toUpperCase()) < 0
evaluates to true and 2nd retry won't happen.
Please look into the issue, I'm stuck in some very important project or allow me to debug this furthermore, let see if I can find a cause from where Array is turning into Object Thanks.
@JustinBeckwith I have setup a small environment on Repl.it to test it. Here https://repl.it/@seahindeniz/RaxRetryingIssue
According to the printouts from @morevolk-latei, the keys in the object form are now strings instead of integers.
If so, the fix can be pretty simple - just replace
if (typeof key === 'number') {
arr[key] = obj[key];
}
with
const idx = parseInt(key, 10);
if (!isNaN(idx)) {
arr[idx] = obj[key];
}
Here is a full example for timeout error:
import axios from 'axios';
import * as rax from 'retry-axios';
const axiosConf = {
timeout: 1000,
raxConfig: {
retry: 3,
noResponseRetries: 3,
httpMethodsToRetry: ['POST'],
onRetryAttempt: (err) => {
const cfg = rax.getConfig(err);
console.log(`Retry attempt #${cfg?.currentRetryAttempt} (after ${err.code} for URL ${err.config?.url})`);
}
}
};
try {
const axiosClient = axios.create();
rax.attach(axiosClient);
const res = await axiosClient.post('http://httpbin.org/delay/2', {}, axiosConf);
console.log(res.data);
} catch (err) {
console.error(err.message);
}
Output:
Retry attempt #1 (after ECONNABORTED for URL http://httpbin.org/delay/2)
timeout of 1000ms exceeded
Here is a simple example with error code:
import axios from 'axios';
import * as rax from 'retry-axios';
try {
const axiosClient = axios.create();
rax.attach(axiosClient);
console.log('Sending request');
const res = await axiosClient.get('http://httpbin.org/status/503', {
raxConfig: {
retry: 3,
noResponseRetries: 3,
onRetryAttempt: (err) => {
const cfg = rax.getConfig(err);
console.log(`Retry attempt #${cfg?.currentRetryAttempt} (after ${err.code} for URL ${err.config?.url})`);
}
}
});
console.log(res.data);
} catch (err) {
console.log(err.message);
}
Output:
Sending request
Retry attempt #1 (after ERR_BAD_RESPONSE for URL http://httpbin.org/status/503)
Request failed with status code 503
:tada: This issue has been resolved in version 3.1.2 :tada:
The release is available on:
Your semantic-release bot :package::rocket: