Skip to content

retry-axios: v4.0.0

Choose a tag to compare

@github-actions github-actions released this 20 Oct 21:55
Immutable release. Only release title and notes can be modified.
f4e641f

4.0.0 (2025-10-20)

⚠ BREAKING CHANGES

This major release includes several breaking changes that simplify the API and improve consistency. Please review the migration guide below for each change.

1. Node.js Version Requirements

This library now requires Node.js 20 or higher. Previous versions supported Node.js 6, 8, 12, and 14, which are all now end-of-life.

Migration Required: Upgrade your Node.js version to 20 or higher before upgrading to retry-axios 4.0.

# Check your Node.js version
node --version

# If below v20, upgrade Node.js first
# Visit https://nodejs.org or use a version manager like nvm

2. Removal of config.instance Option

The config.instance option has been removed. The axios instance is now automatically used from the interceptor attachment point.

This was confusing because users had to specify the instance twice - once in raxConfig and once in rax.attach(). Now you only specify it once in rax.attach().

Before (v3.x):

const myAxiosInstance = axios.create();
myAxiosInstance.defaults.raxConfig = {
  instance: myAxiosInstance,  // ❌ Remove this
  retry: 3
};
rax.attach(myAxiosInstance);

After (v4.0):

const myAxiosInstance = axios.create();
myAxiosInstance.defaults.raxConfig = {
  retry: 3  // ✅ Instance is automatically used from rax.attach()
};
rax.attach(myAxiosInstance);

Migration Required: Remove the instance property from your raxConfig objects.

3. Simplified Retry Configuration - Removal of noResponseRetries

The noResponseRetries configuration option has been removed. The retry option now controls the maximum number of retries for ALL error types (both response errors like 5xx and network errors like timeouts).

This simplifies the API to match industry standards. Popular libraries like axios-retry, Got, and Ky all use a single retry count.

Before (v3.x):

raxConfig: {
  retry: 3,              // For 5xx response errors
  noResponseRetries: 2   // For network/timeout errors
}

After (v4.0):

raxConfig: {
  retry: 3  // For ALL errors (network + response errors)
}

If you need different behavior for network errors vs response errors, use the shouldRetry callback:

raxConfig: {
  retry: 5,
  shouldRetry: (err) => {
    const cfg = rax.getConfig(err);

    // Network error (no response) - allow up to 5 retries
    if (!err.response) {
      return cfg.currentRetryAttempt < 5;
    }

    // Response error (5xx, 429, etc) - limit to 2 retries
    return cfg.currentRetryAttempt < 2;
  }
}

Migration Required:

  • If you used noResponseRetries, remove it and adjust your retry value as needed
  • If you need different retry counts for different error types, implement a shouldRetry function

4. onRetryAttempt Now Requires Async Functions

The onRetryAttempt callback must now return a Promise. It will be awaited before the retry attempt proceeds. If the Promise is rejected, the retry will be aborted.

Additionally, the timing has changed: onRetryAttempt is now called AFTER the backoff delay (right before the retry), not before. A new onError callback has been added that fires immediately when an error occurs.

Before (v3.x):

raxConfig: {
  onRetryAttempt: (err) => {
    // Synchronous callback, called before backoff delay
    console.log('About to retry');
  }
}

After (v4.0):

raxConfig: {
  // Called immediately when error occurs, before backoff delay
  onError: async (err) => {
    console.log('Error occurred, will retry after backoff');
  },

  // Called after backoff delay, before retry attempt
  onRetryAttempt: async (err) => {
    console.log('About to retry now');
    // Can perform async operations like refreshing tokens
    const token = await refreshAuthToken();
    // If this throws, the retry is aborted
  }
}

Common use case - Refreshing authentication tokens:

raxConfig: {
  retry: 3,
  onRetryAttempt: async (err) => {
    // Refresh expired token before retrying
    if (err.response?.status === 401) {
      const newToken = await refreshToken();
      // Update the authorization header for the retry
      err.config.headers.Authorization = `Bearer ${newToken}`;
    }
  }
}

Migration Required:

  • Change onRetryAttempt to be an async function or return a Promise
  • If you need immediate error notification (old onRetryAttempt timing), use the new onError callback instead
  • If your callback throws or rejects, be aware this will now abort the retry

Summary of All Breaking Changes

  1. Node.js 20+ required - Drops support for Node.js 6, 8, 12, and 14
  2. Remove config.instance - Axios instance is now automatically used from rax.attach()
  3. Remove noResponseRetries - Use retry for all error types, or implement shouldRetry for custom logic
  4. onRetryAttempt must be async - Must return a Promise, called after backoff delay (use onError for immediate notification)

Features

  • accept promises on config.onRetryAttempt (#23) (acfbe39)
  • add configurable backoffType (#76) (6794d85)
  • Add jitter support and use retryDelay as base for exponential backoff (#314) (7436b59)
  • Add retriesRemaining property to track remaining retry attempts (#316) (2d1f46b)
  • add support for cjs (#291) (38244be)
  • add support for configurable http methods (819855c)
  • add support for noResponseRetries (d2cfde7)
  • add support for onRetryAttempt handler (fa17de4)
  • add support for overriding shouldRetry (76fcff5)
  • add support for statusCodesToRetry (9283c9e)
  • allow retryDelay to be 0 (#132) (57ba46f)
  • Collect all errors in errors array during retry attempts (#315) (a7ae9e1)
  • configurable maxRetryDelay (#165) (b8842d7)
  • drop support for node.js 6, add 12 (78ea044)
  • export the shouldRetryRequest method (#74) (694d638)
  • produce es, common, and umd bundles (#107) (62cabf5)
  • Remove redundant config.instance option (#312) (402723d)
  • ship source maps (#223) (247fae0)
  • Simplify retry configuration API (#311) (cb447b3)
  • support retry-after header (#142) (5c6cace)
  • support the latest versions of node.js (#188) (ef74217)
  • umd compatibility with babel 7.x (#21) (f1b336c)

Bug Fixes

  • added check for cancel tokens (#99) (734a93f)
  • Call onRetryAttempt after backoff timeout (#307) (a5457e4)
  • cannot set propery raxConfig of undefined (#114) (0be8578)
  • deps: update dependency gts to v1 (#45) (1dc0f2f)
  • Don't store counter on input config object (#98) (c8ceec0), closes #61
  • ensure config is set (#81) (88ffd00)
  • fix instructions and test for non-static instnaces (544c2a6)
  • Fix potential exception when there is no response (#258) (a58cd1d)
  • Fix workaround for arrays that are passed as objects (#238) (6e2454a)
  • handle arrays that are converted to objects (#83) (554fd4c)
  • include files in the release (#29) (30663b3)
  • non-zero delay between first attempt and first retry for linear and exp strategy (#163) (e63ca08)
  • onRetryAttempt does not handle promise rejection (#306) (6f5ecc2)
  • preserve configuration for custom instance (#240) (2e4e702)
  • Respect retry limit when using custom shouldRetry (#309) (58f6fa6)
  • typescript: include raxConfig in native axios types (#85) (b8b0456)
  • Update tsconfig.json to emit index.d.ts (#229) (bff6aa9)

Miscellaneous Chores

Build System