retry-axios: Exception in function shouldRetryRequest() when checking HTTP methods to retry

In function shouldRetryRequest there’s this block of code

    // Only retry with configured HttpMethods.
    if (!err.config.method ||
        config.httpMethodsToRetry.indexOf(err.config.method.toUpperCase()) < 0) {
        return false;
    }

that fails evaluating second condition, because httpMethodsToRetry is an object, not an array.

Below goes the output from dev console, when the breakpoint was set on the line given above ^^^:

config.httpMethodsToRetry
{0: "GET", 1: "HEAD", 2: "OPTIONS", 3: "DELETE", 4: "PUT"}

That looks different from what gets set in raxConfig

    const raxConfig = {
    ....
        
      // HTTP methods to automatically retry.  Defaults to:
      // ['GET', 'HEAD', 'OPTIONS', 'DELETE', 'PUT']
      httpMethodsToRetry: ['GET', 'HEAD', 'OPTIONS', 'DELETE', 'PUT'],
    }

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 6
  • Comments: 16 (4 by maintainers)

Commits related to this issue

Most upvoted comments

@JustinBeckwith

v0.19.0-beta.1. Please see my comment. Now options are completely whitelisted and it doesn’t accept raxConfig.

I am also getting error,

Here is my relevant code,

axios.defaults.raxConfig= {
  // Retry 3 times on requests that return a response (500, etc) before giving up.  Defaults to 3.
  retry: 3,

  // Retry twice on errors that don't return a response (ENOTFOUND, ETIMEDOUT, etc).
  noResponseRetries: 3,

  // Milliseconds to delay at first.  Defaults to 100.
  retryDelay: 0,

  // HTTP methods to automatically retry.  Defaults to:
  // ['GET', 'HEAD', 'OPTIONS', 'DELETE', 'PUT']
  httpMethodsToRetry: ['GET', 'DELETE', 'PUT', 'POST'],

  // The response status codes to retry.  Supports a double
  // array with a list of ranges.  Defaults to:
  // [[100, 199], [429, 429], [500, 599]]
  httpStatusCodesToRetry: [[100, 199], [429, 429], [500, 599]],

  // If you are using a non static instance of Axios you need
  // to pass that instance here (const ax = axios.create())
  instance: axios,

  // You can detect when a retry is happening, and figure out how many
  // retry attempts have been made
  onRetryAttempt: (err) => {
    const cfg = rax.getConfig(err);
    console.log(`Retry attempt #${cfg.currentRetryAttempt}`);
  }
};
const id = rax.attach(axios);

And here is the error,

TypeError: config.httpMethodsToRetry.indexOf is not a function
    at shouldRetryRequest (/Users/chaityashah/FracTEL/skrum/node_modules/retry-axios/build/src/index.js:96:35)
    at onError (/Users/chaityashah/FracTEL/skrum/node_modules/retry-axios/build/src/index.js:58:10)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

🎉 This issue has been resolved in version 2.0.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

I wrote https://github.com/googleapis/gaxios/ to be that drop in replacement based on node-fetch 🙃 It’s part of the reason I don’t spend a ton of time in this particular module. It has retries baked in.

also had this issue. An effective workaround for the moment is to pass a custom shouldRetry function and check the type of config.httpMethodsToRetry and get the values into something useful before checking. Not ideal, but relatively easy to fix until a new version of axios is released which resolves the issue.

I am getting this, too.

Here’s my relevant code.

import Axios from 'axios';
import { attach as raxAttach, getConfig as raxConfig } from 'retry-axios';

const createAxios = () => {
  const http = Axios.create();
  http.defaults.timeout = 60*1000;
  http.defaults.validateStatus = (status) => (status >= 200 && status < 300) || (status == 404);
  http.defaults.raxConfig = {
    instance: http,
    retry: 5,
    noResponseRetries: 100,
    retryDelay: 250,
    httpStatusCodesToRetry: [[100, 199], [420, 429], [500, 599]],
    onRetryAttempt: (err) => {
      try {
        console.info("Retrying request", err, raxConfig(err))
      } catch(e) {
        throw new Error("Error logging the retry of a request: " + e);
      }
    },
  };
  raxAttach(http);
  return http;
};

@mpyw shall we create separate issues for the peer dependency and whitelisting stuff?

I debugged this issue and found the root of the problem in the Axios package.

The issue only happens on retry, and the reason is because of a configuration merge function that converts the httpMethodsToRetry and statusCodesToRetry arrays to objects.

Offending line here: https://github.com/axios/axios/blob/ad1195f0702381a77b4f2863aad6ddb1002ffd51/lib/core/Axios.js#L35

It appears that this merge function has entirely changed (with deep-copy fixes) for v0.18.x releases, which are yet to be released.