⏱️ Don’t Wait Forever for Slow APIs
Requests can hang indefinitely. Timeout cancels after specified time. Better UX, error handling, retry logic.
📝 Fetch with Timeout
// AbortController for fetch timeout
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch('/api/data', {
signal: controller.signal
});
clearTimeout(timeoutId);
const data = await response.json();
} catch (error) {
if (error.name === 'AbortError') {
console.log('Request timed out after 5 seconds');
showRetryButton();
}
}
🎯 Reusable Timeout Function
function fetchWithTimeout(url, options = {}, timeout = 5000) {
const controller = new AbortController();
const { signal } = controller;
const timeoutId = setTimeout(() => controller.abort(), timeout);
return fetch(url, { ...options, signal })
.finally(() => clearTimeout(timeoutId));
}
// Usage
try {
const response = await fetchWithTimeout('/api/slow', {}, 3000);
const data = await response.json();
} catch (err) {
if (err.name === 'AbortError') {
console.log('Request timed out');
}
}
// With retry
async function fetchWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fetchWithTimeout(url, {}, 5000);
} catch (err) {
if (i === maxRetries - 1) throw err;
await new Promise(r => setTimeout(r, 1000 * (i + 1)));
}
}
}
💡 Best Practices
- Set reasonable timeouts (3-10 seconds for APIs)
- Longer for file uploads (based on file size)
- Show user feedback when timeout occurs
- Implement retry for transient failures
- AbortController also cancels on component unmount (React)
“Slow API hung for 60 seconds. Added 5-second timeout. Now shows error message, user can retry. Better UX than infinite spinner.”
