Skip to content

Latest commit

 

History

History
142 lines (115 loc) · 3.74 KB

File metadata and controls

142 lines (115 loc) · 3.74 KB

retry

Retries a Promise-returning function until it succeeds.

const result = await retry(asyncFunc, options);

Usage

retry(func, options?)

Use retry when you want to automatically retry an asynchronous function that fails. This is useful for operations that can temporarily fail, such as API calls or network requests.

You can configure the number of retries, retry interval, and cancellation signal. The retry interval can be a fixed value or a function that dynamically calculates based on the retry count.

import { retry } from 'es-toolkit/function';

// Basic usage (infinite retries)
const data1 = await retry(async () => {
  const response = await fetch('/api/data');
  if (!response.ok) throw new Error('Failed to fetch');
  return response.json();
});

// Limit retry count
const data2 = await retry(async () => {
  return await fetchData();
}, 3);

// Set retry interval (100ms)
const data3 = await retry(
  async () => {
    return await fetchData();
  },
  {
    retries: 3,
    delay: 100,
  }
);

// Dynamic retry interval (exponential backoff)
const data4 = await retry(
  async () => {
    return await fetchData();
  },
  {
    retries: 5,
    delay: attempts => Math.min(100 * Math.pow(2, attempts), 5000),
  }
);

// Error-based retry interval (e.g., respect Retry-After headers)
const data5 = await retry(
  async () => {
    return await fetchData();
  },
  {
    retries: 3,
    delay: (_attempts, error) => {
      if (error instanceof ResponseError && error.status === 429) {
        return error.retryAfter * 1000;
      }
      return 1000;
    },
  }
);

You can use shouldRetry option when you want to retry only on specific errors.

import { retry } from 'es-toolkit/function';

class NetworkError extends Error {
  constructor(public status: number) {
    super(`Network error: ${status}`);
  }
}

// Retry only on 500+ errors
const data6 = await retry(
  async () => {
    const response = await fetch('/api/data');
    if (!response.ok) {
      throw new NetworkError(response.status);
    }
    return response.json();
  },
  {
    retries: 3,
    shouldRetry: (error, attempt) => error instanceof NetworkError && error.status >= 500,
  }
);

You can also cancel retries using AbortSignal.

import { retry } from 'es-toolkit/function';

const controller = new AbortController();

// Cancel retry after 5 seconds
setTimeout(() => controller.abort(), 5000);

try {
  const data = await retry(
    async () => {
      return await fetchData();
    },
    {
      retries: 10,
      delay: 1000,
      signal: controller.signal,
    }
  );
  console.log(data);
} catch (error) {
  console.log('Retry was canceled or failed:', error);
}

Parameters

  • func (() => Promise<T>): The asynchronous function to retry.
  • options (number | RetryOptions, optional): The number of retries or options object.
    • retries (number, optional): The number of times to retry. Defaults to Infinity for infinite retries.
    • delay (number | (attempts: number, error: unknown) => number, optional): The retry interval (in milliseconds). Can be a number or a function. The function receives the attempt number and the error object. Defaults to 0.
    • signal (AbortSignal, optional): A signal that can cancel retries.
    • shouldRetry ((error: unknown, attempt: number) => boolean, optional): A function that determines whether to retry. If it returns false, the error is thrown immediately.
      • error: The error object that occurred.
      • attempt: The current attempt count (starting from 0).

Returns

(Promise<T>): Returns the result of the successfully executed function.

Throws

Throws the last error when the retry count is exceeded or when canceled by AbortSignal.