Timeout and Retries

Configure automatic retries and request timeouts

Timeout

Set a maximum time limit for requests using the timeout option (in milliseconds). If a request takes longer than the specified timeout, it will be aborted and a TimeoutError will be returned:

api.ts
import { createFetchClient } from "@zayne-labs/callapi";

const callBackendApi = createFetchClient({
	baseURL: "http://localhost:3000",
	timeout: 5000,
});

const result = await callBackendApi("/api/users", {
	timeout: 10000,
});

Auto Retry

CallApi can automatically retry failed requests. For most use cases, you only need to specify the number of retry attempts:

api.ts
const result = await callApi("/api/users", {
	retryAttempts: 3,
});

Advanced Retry Options

CallApi provides flexible retry mechanisms with both linear and exponential backoff strategies.

Linear Retry Strategy

Waits a fixed amount of time between retries:

api.ts
const result = await callApi("/api/users", {
	retryStrategy: "linear",
	retryAttempts: 3,
	retryDelay: 1000,
});

Exponential Retry Strategy

Increases the delay between retries exponentially. This is the recommended strategy for most APIs to prevent overwhelming servers.

api.ts
const result = await callApi("/api/users", {
	retryStrategy: "exponential",
	retryAttempts: 5, // Retry up to 5 times
	retryDelay: 1000, // Start with 1 second delay
	retryMaxDelay: 10000, // Cap the delay at 10 seconds
	// Retry delays will be: 1s, 2s, 4s, 8s, 10s (capped at maxDelay)
});

Dynamic Retry Delay

Pass a function to retryDelay to dynamically calculate the delay based on the current attempt count:

api.ts
const result = await callApi("/api/data", {
	retryAttempts: 5,
	retryDelay: (attemptCount) => {
		// Example: Add random jitter to prevent thundering herd
		const baseDelay = 1000 * 2 ** attemptCount;
		const jitter = Math.random() * 1000;
		return Math.min(baseDelay + jitter, 10000);
	},
});

Retry Methods and Status Codes

Customize when to retry a request with retryMethods and retryStatusCodes:

  1. Retry Methods: Specifies which HTTP methods should be retried. Defaults to ["GET", "POST"]. Be careful when configuring this to retry PUT or DELETE requests unless they are idempotent.

  2. Retry Status Codes: Specifies which HTTP status codes should be retried. If not specified, all error status codes are eligible for retry.

api.ts
const result = await callApi("/api/users", {
	retryAttempts: 3,
	retryDelay: 1000,
	retryMethods: ["GET", "POST"],
	// Only retry on rate limits and server errors
	retryStatusCodes: [429, 500, 502, 503, 504],
});

Custom Retry Condition

Use retryCondition to implement custom retry logic. This function receives the error context and returns a boolean (or promise) indicating whether to retry:

api.ts
const result = await callApi("/api/users", {
	retryAttempts: 3,

	retryCondition: ({ error, response }) => {
		return response?.status === 429;
	},
});

The onRetry hook

Listen to retry attempts using the onRetry hook:

api.ts
const result = await callApi("/todos/1", {
	retryAttempts: 3,

	onRetry: ({ retryAttemptCount, error }) => {
		console.log(`Retrying request (attempt ${retryAttemptCount}). Reason: ${error.message}`);
	},
});

Manual Refetching

While retryAttempts handles automatic retries for common scenarios, sometimes you need more control—like refreshing an expired authentication token before retrying.

In these cases, you can use the refetch() function available in most error-related hooks. See the Manual Refetching section in the Hooks documentation for more details.

Types

Timeout

Prop

Type

Retry

Prop

Type

Edit on GitHub

Last updated on

On this page