Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I set retry 3 times,but only retry 1 times #68

Closed
CatcherRao opened this issue Sep 29, 2019 · 12 comments · Fixed by #240
Closed

I set retry 3 times,but only retry 1 times #68

CatcherRao opened this issue Sep 29, 2019 · 12 comments · Fixed by #240
Labels
needs info I need more information! released

Comments

@CatcherRao
Copy link

CatcherRao commented Sep 29, 2019

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);
    }
  }
@CatcherRao CatcherRao changed the title I set retry 5 times,but only retry 1 times I set retry 3 times,but only retry 1 times Sep 29, 2019
@tehaksbrid
Copy link

tehaksbrid commented Dec 4, 2019

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

@JustinBeckwith JustinBeckwith added bug Something isn't working needs info I need more information! and removed bug Something isn't working labels Jan 11, 2020
@JustinBeckwith
Copy link
Owner

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.

@tehaksbrid
Copy link

@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.

@dvicagolf
Copy link

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!

@yoshigev
Copy link
Contributor

Note that #61 was fixed, so this issue is probably also fixed.

@JustinBeckwith
Copy link
Owner

Sweet. Could I trouble anyone to try it and take a look?

@morevolk-latei
Copy link

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.
First time error - rax config

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
Second time error - rax config

now for this error when shouldRetryRequest function called see the config now.
Should retry method rax config

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.

@seahindeniz
Copy link

@JustinBeckwith I have setup a small environment on Repl.it to test it. Here https://repl.it/@seahindeniz/RaxRetryingIssue

@khitrenovich
Copy link

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];
      }

@orgads
Copy link
Contributor

orgads commented Nov 15, 2023

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

@orgads
Copy link
Contributor

orgads commented Nov 15, 2023

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

Copy link

🎉 This issue has been resolved in version 3.1.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs info I need more information! released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants