Axios Retry Interceptor With Exponential Backoff

Implement response-layer retry in Axios via a custom interceptor with attempt counters, exponential backoff, and idempotency-aware opt-in.

JavascriptResilience

Code

snippet
import axios from 'axios';

const client = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 8000,
  headers: { 'x-client': 'batch-sync/1.2' },
});

client.interceptors.response.use(
  (res) => res,
  async (error) => {
    const config = error.config ?? {};
    const retries = config.__retries ?? 0;
    const idempotent = ['GET', 'HEAD', 'PUT', 'DELETE'].includes(config.method);

    const transient = error.response
      && [429, 502, 503, 504].includes(error.response.status);

    if (!idempotent || !transient || retries >= 3) {
      return Promise.reject(error);
    }

    config.__retries = retries + 1;
    const delay = 2 ** config.__retries * 500;
    await new Promise((r) => setTimeout(r, delay));
    return client(config);
  },
);

const data = await client.get('/catalog?page=2');
console.log('items:', data.data.items.length);