JAVASCRIPT
Handling API Rate Limits with Retry Logic
Implement robust client-side retry logic for API requests to gracefully handle 429 Too Many Requests errors and improve application resilience.
async function fetchWithRetry(url, options = {}, retries = 3, backoff = 1000) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (response.status === 429) { // Too Many Requests
const retryAfter = response.headers.get('Retry-After');
const delay = retryAfter ? parseInt(retryAfter, 10) * 1000 : backoff * Math.pow(2, i);
console.warn(`Rate limit hit. Retrying in ${delay / 1000} seconds...`);
await new Promise(resolve => setTimeout(resolve, delay));
continue; // Try again
}
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(`Attempt ${i + 1} failed:`, error.message);
if (i === retries - 1) throw error; // Re-throw if all retries exhausted
// For network errors or other non-429s, apply a basic backoff before retrying
await new Promise(resolve => setTimeout(resolve, backoff * Math.pow(2, i)));
}
}
throw new Error('All retry attempts failed.');
}
// Example usage:
// fetchWithRetry('https://api.example.com/limited-resource', {}, 5)
// .then(data => console.log('Successfully fetched after potential retries:', data))
// .catch(error => console.error('Failed after all retries:', error));
How it works: This JavaScript snippet provides a robust solution for handling API rate limits by implementing client-side retry logic with exponential backoff. The `fetchWithRetry` function attempts an API call and, if it encounters a `429 Too Many Requests` status, it waits before retrying. It first checks for a `Retry-After` header provided by the API; if present, it uses that delay. Otherwise, it uses an exponential backoff strategy. This approach helps prevent overwhelming the API during temporary rate limit bursts and improves the reliability of your application's API interactions.