Soal 1Apa yang ditampilkan try { console.log(1); } finally { console.log(2); }?
Menangkap Exception — try / catch / finally
Tangkap exception dengan try dan catch, jalankan proses bersih-bersih di finally, lempar ulang dengan throw, dan bedakan penanganan menurut jenis error.
Saat kamu memakai JSON.parse untuk mengubah string yang diterima kembali menjadi object, cukup satu karakter yang salah untuk menghentikan eksekusi di baris itu, dan kode tampilan maupun penyimpanan yang kamu tulis di bawahnya tidak pernah jalan. Lagi pula, tidak semua penyebabnya bisa kamu cegah lebih dulu dengan if.
Artikel ini membahas try / catch untuk menangkap exception yang menghentikan kode, dan finally, blok yang selalu dijalankan.
Menangkap Proses yang Berhenti — try dan catch
Misalnya kamu mau mem-parse string pengaturan yang diterima dari server, lalu menerapkannya ke halaman. Kalau bentuk string-nya rusak, JSON.parse melempar exception (error yang menghentikan proses di tengah jalan) di baris itu, dan tidak ada satu pun baris di bawahnya yang dijalankan. Halaman tetap kosong dan prosesnya berhenti begitu saja.
Kalau exception terjadi di dalam try (blok yang membungkus kode yang mungkin gagal), eksekusi pindah ke catch (blok yang menerima exception). error di catch (error) hanyalah nama yang kamu berikan untuk value yang diterima (diganti err atau nama lain pun tetap jalan). Value ini punya name (nama jenis error-nya) dan message (teks penjelasannya).
// String yang masih menyisakan koma di akhir
const configText = '{"theme":"dark","fontSize":14,}';
try {
const config = JSON.parse(configText);
console.log(config.theme); // baris ini tidak dijalankan
} catch (error) {
// eksekusi pindah ke sini saat exception terjadi
console.log("Gagal memuat pengaturan"); // Gagal memuat pengaturan
console.log(error.name); // SyntaxError
}
// karena ada catch, baris berikutnya tetap jalan
console.log("Menampilkan pengaturan default"); // Menampilkan pengaturan default
Setelah pindah ke catch, eksekusi tidak kembali untuk menyelesaikan baris yang melempar exception, jadi tulis tampilan pengganti atau default value di dalam catch. Isi message berbeda-beda tergantung browser, jadi baca name kalau kamu perlu membedakan jenis error.
Tetap Dijalankan Saat Berhasil Maupun Gagal — finally
Proses bersih-bersih seperti menyembunyikan indikator loading atau menutup koneksi yang terbuka tetap diperlukan, baik prosesnya berhasil maupun gagal. Kalau baris yang sama kamu tulis di try dan catch, suatu saat kamu bisa memperbaiki satu salinan dan lupa yang lain, sehingga kedua jalurnya tidak lagi berperilaku sama.
finally (blok yang selalu dijalankan saat keluar dari try) ditulis setelah catch. Entah try jalan sampai selesai atau catch menerima exception, blok ini selalu dijalankan tepat sebelum keluar. catch juga boleh dihilangkan, jadi cukup try dan finally.
function loadReport(text) {
try {
const report = JSON.parse(text);
console.log(report.title);
} catch (error) {
console.log("Gagal memuat");
} finally {
// selalu dijalankan saat keluar dari try
console.log("Indikator loading disembunyikan");
}
}
// Saat berhasil
loadReport('{"title":"Penjualan September"}'); // Penjualan September → Indikator loading disembunyikan
// Saat gagal
loadReport('{"title":}'); // Gagal memuat → Indikator loading disembunyikan
finally dijalankan setelah kode di try atau catch selesai. Karena itu, pada kode di atas, pesan bersih-bersih muncul setelah judul saat berhasil, dan setelah pesan gagal saat gagal.
Variable yang Dideklarasikan di Dalam try Tidak Bisa Dibaca dari Luar
Variable yang dideklarasikan dengan const atau let di dalam try hanya bisa dipakai di dalam blok itu. Kalau kamu membacanya dari catch, finally, atau baris setelahnya, hasilnya ReferenceError. Kalau value-nya perlu dipakai di luar try, deklarasikan variable-nya dengan let sebelum try, lalu di dalam try cukup isi value-nya.
Memberi Tahu Pemanggil — throw di Dalam catch
Misalnya function yang membaca data reservasi menangkap exception dan hanya menulis log. Function itu lalu selesai seperti biasa, sehingga pemanggil tidak sadar ada kegagalan, terus memakai return value-nya, dan akhirnya berhenti lagi di baris lain yang jauh dari penyebab aslinya.
Kalau error yang diterima catch langsung kamu berikan ke throw (statement yang melempar exception), exception yang sama diteruskan ke pemanggil. Function-nya tetap bisa mencatat kegagalan itu sendiri, sementara keputusan cara menanganinya diserahkan ke pemanggil.
function readEntry(text) {
try {
return JSON.parse(text);
} catch (error) {
console.log(`Data reservasi tidak bisa dibaca: ${error.name}`);
throw error; // lempar ulang exception yang diterima apa adanya
}
}
try {
const entry = readEntry('{"name":"Siti","seats":}');
console.log(entry.name); // baris ini tidak dijalankan
} catch (error) {
console.log("Reservasi dibatalkan"); // Reservasi dibatalkan
}
Kalau exception yang ditangkap di dalam function juga perlu ditangani oleh pemanggil, lempar ulang dengan menulis throw error; di akhir catch. Baris setelah throw tidak dijalankan, jadi tulis kode pencatatan log sebelum throw.
catch yang Kosong Menghilangkan Jejak Kegagalan
Kalau catch (error) { } dibiarkan kosong, exception-nya seolah hilang, tapi kegagalan itu tidak tercatat di mana pun, sehingga penyebabnya tidak bisa dilacak nanti. Akibat yang paling sering muncul adalah halaman yang tetap kosong. Selalu lakukan minimal salah satu dari ini: tampilkan pesan, pakai default value, atau lempar ulang.
Membedakan Menurut Jenis Error — instanceof dan name
catch menerima semua exception, apa pun jenisnya. Padahal pesan yang mau kamu tampilkan ke pengguna berbeda, tergantung apakah bentuk datanya rusak atau value yang mau dibaca ternyata tidak ada.
Dengan instanceof (operator yang mengecek apakah value di kiri dibuat dari jenis di kanan), kamu bisa mengecek jenisnya seperti error instanceof SyntaxError. error.name juga menyimpan nama jenis yang sama dalam bentuk string.
const applicant = { name: "Budi", contact: null };
try {
console.log(applicant.contact.email);
} catch (error) {
if (error instanceof SyntaxError) {
console.log("Format datanya tidak valid"); // tidak sampai ke sini
} else if (error instanceof TypeError) {
console.log("Value yang mau dibaca tidak ada"); // Value yang mau dibaca tidak ada
} else {
console.log(`Jenis error tak terduga: ${error.name}`);
}
console.log(error.name); // TypeError
}
catch (error) yang sama, tapi name-nya berbeda. Dengan mengecek jenisnya, kamu bisa menampilkan pesan yang berbeda.Exception yang tidak cocok dengan pengecekan mana pun ditampung oleh else terakhir. Tabel di bawah berisi empat jenis yang sering kamu temui dan kapan masing-masing terjadi.
| Jenis | Kapan terjadi | Contoh kode yang memicunya |
|---|---|---|
| SyntaxError | String-nya tidak berbentuk JSON | JSON.parse("{,}") |
| TypeError | Membaca property null atau undefined | applicant.contact.email |
| RangeError | Value di luar rentang, misal jumlah digit | (1980).toFixed(200) (maksimal 100 digit) |
| ReferenceError | Membaca nama yang tak dideklarasikan | console.log(total) |
Cek Pemahaman
Jawab setiap pertanyaan satu per satu.
Soal 2Kalau catch di dalam function hanya menulis log tanpa throw error;, return value apa yang diterima pemanggil?
Soal 3Operator mana yang dipakai untuk mengecek jenis error yang diterima catch?