Cara mengatasi fetch API timeout JavaScript paling cepat adalah membungkus fetch() dengan AbortController dan setTimeout(). Fetch tidak menyediakan opsi timeout bawaan, jadi request yang servernya lambat akan menggantung sampai koneksi putus sendiri.
Penyebab Fetch Timeout di Browser
Promise dari fetch() tetap berstatus pending selama browser menunggu respons. Timeout bukan error HTTP, melainkan request yang dihentikan paksa oleh kode kamu.
- Server lambat memproses atau query database berat.
- Koneksi pengguna lemah, paket hilang, atau DNS lambat.
- Endpoint salah, salah method, atau server tidak pernah merespons.
- Tidak ada
AbortController, sehingga tidak ada batas waktu.
Bedakan empat kegagalan ini: network error berarti request tidak sampai, HTTP error berarti server menjawab status 404 atau 500, JSON parse error berarti body bukan JSON valid, sedangkan timeout murni berarti respons tidak datang dalam batas waktu.
Tabel Troubleshooting Fetch Timeout
Periksa response.ok untuk status 200-299, baca response.status untuk kode pasti, dan kenali AbortError sebagai tanda abort dari controller.signal.
| Error/Kondisi | Penyebab | Solusi |
|---|---|---|
| Request menggantung | Tanpa timeout | Tambahkan AbortController 8 detik |
| Failed to fetch | Offline atau CORS | Cek koneksi dan header server |
| HTTP 404/500 | Endpoint atau server error | Perbaiki URL, cek log server |
| JSON parse error | Respons HTML atau kosong | Validasi content-type sebelum parse |
Cara Memperbaiki Fetch Timeout dengan AbortController
1. Buat new AbortController() sebelum request.
2. Pasang setTimeout() 8.000 ms yang memanggil controller.abort().
3. Kirim controller.signal ke opsi fetch().
4. Panggil clearTimeout() setelah respons datang.
5. Tangkap AbortError secara khusus di catch.
async function fetchWithTimeout(url, ms = 8000, retries = 2) {
for (let i = 0; i <= retries; i++) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), ms);
try {
const res = await fetch(url, { signal: controller.signal });
clearTimeout(id);
if (!res.ok) throw new Error("HTTP " + res.status);
return await res.json();
} catch (err) {
clearTimeout(id);
if (err.name === "AbortError" && i < retries) continue;
throw err;
}
}
}
signal menghubungkan fetch ke controller, abort() membatalkannya. AbortError berarti kamu yang membatalkan, sedangkan TypeError: Failed to fetch berarti jaringan atau CORS yang gagal.
Cara Mencegah Timeout Terulang
- Batasi retry maksimal 2-3 kali dengan jeda 1-2 detik.
- Tampilkan indikator loading dan tombol Batal.
- Catat endpoint lambat, lalu optimalkan atau ganti endpoint.
Ulangi request hanya untuk AbortError dan network error sesaat. Ganti endpoint bila selalu 404, cek server bila selalu 500 atau lambat di semua jaringan.
FAQ
Apakah fetch punya timeout bawaan?
Tidak, fetch di browser tidak memiliki timeout bawaan.
Berapa batas timeout ideal untuk fetch?
Umumnya 8-10 detik untuk API biasa dan lebih pendek untuk pencarian otomatis.
Apa arti error AbortError saat fetch timeout?
Artinya request dibatalkan oleh AbortController karena melewati batas waktu.