JAVASCRIPT
Implement API Call Retries with Exponential Backoff
Enhance API integration reliability by implementing an exponential backoff retry mechanism for failed requests, preventing overwhelming the server and improving fault tolerance.
async function fetchWithRetry(url, options = {}, retries = 3, backoffFactor = 2, initialDelay = 1000) {
let delay = initialDelay;
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url, options);
if (response.status >= 500 && response.status < 600) {
// Server error, try again
throw new Error(`Server error: ${response.status}`);
}
if (!response.ok) {
// Other client errors (e.g., 400, 401, 403, 404) are not typically retried
const errorData = await response.json().catch(() => ({}));
throw new Error(`HTTP error! Status: ${response.status}, Message: ${errorData.message || 'Unknown error'}`);
}
return await response.json(); // Or response.text() depending on content type
} catch (error) {
console.warn(`Attempt ${i + 1} failed: ${error.message}. Retrying in ${delay / 1000}s...`);
if (i < retries - 1) {
await new Promise(resolve => setTimeout(resolve, delay));
delay *= backoffFactor; // Exponential increase
} else {
throw new Error(`Max retries exceeded for ${url}: ${error.message}`);
}
}
}
}
// Example usage:
const API_URL = 'https://api.example.com/unstable-service';
const MY_API_KEY = 'your_secret_api_key';
const requestOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${MY_API_KEY}`
}
};
fetchWithRetry(API_URL, requestOptions, 5, 2, 500) // 5 retries, 2x backoff, 0.5s initial delay
.then(data => console.log('Successfully fetched with retries:', data))
.catch(error => console.error('Failed after retries:', error.message));
How it works: This JavaScript snippet implements a robust API call function with automatic retries and exponential backoff. It wraps the `fetch` API within a loop, retrying requests that fail due to network issues or server-side (5xx) errors. After each failure, it waits for an exponentially increasing duration before the next attempt, preventing server overload and increasing the likelihood of success for transient errors. Client-side errors (e.g., 4xx) are generally not retried as they indicate a problem with the request itself rather than a transient issue.