JAVASCRIPT
Client-Side API Retries with Exponential Backoff
Implement an intelligent client-side retry mechanism for API calls using exponential backoff to handle transient network issues or rate limits gracefully.
async function fetchWithRetry(url, options = {}, retries = 3, delay = 1000, factor = 2) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (response.status === 429) { // Too Many Requests (Rate Limit)
console.warn(`Rate limit hit. Retrying in ${delay / 1000}s... (Attempt ${i + 1}/${retries})`);
await new Promise(resolve => setTimeout(resolve, delay));
delay *= factor; // Exponential increase
continue; // Try again
} else if (!response.ok) {
// Treat other non-OK responses as potential retry candidates
// You might want to refine this to specific error codes (e.g., 5xx errors)
console.warn(`API call failed with status ${response.status}. Retrying in ${delay / 1000}s... (Attempt ${i + 1}/${retries})`);
await new Promise(resolve => setTimeout(resolve, delay));
delay *= factor;
continue;
}
return response; // Success!
} catch (error) {
console.error(`Fetch failed (Attempt ${i + 1}/${retries}):`, error.message);
if (i < retries - 1) {
console.info(`Retrying in ${delay / 1000}s...`);
await new Promise(resolve => setTimeout(resolve, delay));
delay *= factor; // Exponential increase
} else {
throw error; // Re-throw if all retries failed
}
}
}
throw new Error('All retry attempts failed.');
}
// Example usage:
// fetchWithRetry('https://api.example.com/data', { method: 'GET' }, 5, 500) // 5 retries, starting delay 0.5s
// .then(response => response.json())
// .then(data => console.log(data))
// .catch(error => console.error('Failed after multiple retries:', error.message));
How it works: This snippet provides a resilient way to interact with APIs by implementing automatic retries with exponential backoff. If an API call fails due to transient network errors (e.g., connection issues) or specific API-side issues like rate limiting (HTTP 429), the function will wait for an increasingly longer duration before attempting the request again, up to a specified number of retries. This pattern significantly improves the robustness of client-side applications by reducing failures caused by temporary conditions.