Error Adalah Objek yang Punya Jenis
Saat JavaScript melempar error, yang kamu terima bukan sekadar string, melainkan sebuah objek. Objek itu punya jenis (constructor-nya) dan beberapa property standar: name, message, dan stack.
err.name adalah label singkat seperti "TypeError". err.message adalah penjelasan yang bisa dibaca manusia. err instanceof TypeError memberi tahu class spesifiknya. Mengetahui jenisnya itu penting: dari situ kamu tahu apakah masalahnya salah ketik, nilai yang salah, atau kode yang bahkan tidak bisa di-parse.
Ada tujuh jenis error bawaan. Tiga akan terus kamu lihat, empat hanya sesekali kamu temui.
SyntaxError: Kodenya Tidak Bisa Di-parse
SyntaxError berarti JavaScript bahkan tidak bisa membaca kodemu. Ini sebenarnya bukan error runtime: engine gagal saat parsing, sebelum satu baris pun berjalan. Kamu tidak bisa menangkap SyntaxError dengan try/catch di file yang sama, karena seluruh file ditolak.
function greet(name {
return "hi, " + name;
}
// SyntaxError: Unexpected token '{'
Kurung yang hilang, koma yang nyasar, return di luar fungsi: apa pun yang merusak tata bahasanya akan memunculkan error ini. Solusinya selalu memperbaiki source code-nya. Satu-satunya tempat kamu bisa menangkap SyntaxError adalah saat parsing dilakukan ketika runtime, seperti JSON.parse:
JSON.parse menerima string saat runtime, jadi syntax error-nya bisa ditangkap. Error di file source code milikmu sendiri tidak bisa.
ReferenceError: Nama Itu Tidak Ada
ReferenceError muncul saat kamu merujuk ke variabel yang belum dideklarasikan di scope mana pun yang bisa dilihat kode saat ini.
Sembilan puluh persen waktu, ini salah ketik (totl padahal maksudnya total). Sepuluh persen sisanya masalah scope: kamu mencoba memakai sesuatu yang dideklarasikan di fungsi atau module lain.
Ada satu penyebab yang lebih halus: temporal dead zone. Deklarasi let dan const sudah ada sejak awal bloknya, tetapi kamu tidak bisa mengaksesnya sebelum baris yang mendeklarasikannya:
x sudah menjadi binding sungguhan saat console.log(x) berjalan, tetapi belum diinisialisasi. Itulah sebabnya muncul reference error. Solusinya pindahkan akses itu ke bawah deklarasinya.
TypeError: Bentuk Nilainya Salah
TypeError berarti sebuah nilai memang ada, tetapi bukan jenis yang diharapkan oleh operasinya. Memanggil sesuatu yang bukan fungsi, membaca property dari null atau undefined, mengisi ulang const: semuanya TypeError.
"Cannot read properties of null (reading 'name')" mungkin adalah pesan error paling umum di JavaScript. Solusinya memastikan nilainya ada, atau melindungi aksesnya dengan optional chaining: user?.name.
Variasi TypeError lainnya:
Memanggil angka, mengisi ulang const, memanggil method yang tidak ada: jenis nilainya salah untuk apa yang kamu minta.
RangeError: Angkanya di Luar Batas
RangeError muncul saat sebuah angka secara teknis valid tetapi berada di luar rentang yang diizinkan untuk operasi tertentu.
Sumber klasiknya adalah rekursi tanpa akhir, yang membuat call stack meluap:
"Maximum call stack size exceeded" hampir selalu berarti sebuah fungsi memanggil dirinya sendiri tanpa base case, atau dua fungsi saling memanggil dalam putaran tanpa henti.
URIError dan EvalError: Yang Jarang Muncul
URIError berasal dari fungsi penanganan URI (encodeURI, decodeURIComponent, dan kerabatnya) saat menerima input yang rusak:
EvalError adalah peninggalan masa lalu. Engine JavaScript modern sebenarnya tidak melemparnya untuk apa pun. Ia masih ada sebagai constructor demi kompatibilitas. Kamu bisa membuatnya secara manual, tetapi tidak akan melihatnya di lapangan.
Rantai Pewarisan
Semua jenis ini mewarisi dari Error dasar. Artinya err instanceof Error bernilai true untuk semuanya, yang berguna di catch yang umum:
Blok catch menangkap semuanya, termasuk nilai yang bukan error kalau seseorang menulis throw "oops". Cabang terakhir itu penting. Selalu persempit dengan instanceof sebelum memperlakukan nilai yang tertangkap sebagai objek error.
Membuat Error dengan Sengaja
Kamu bisa melempar jenis bawaan mana pun sendiri saat kodemu mendeteksi masalah. Pilih jenis yang sesuai dengan kegagalannya:
Menyesuaikan jenis dengan kegagalannya bukan sekadar urusan tampilan: dengan begitu pemanggil bisa menulis logika catch yang tepat sasaran, alih-alih mem-parsing pesan error.
Class Error Buatan Sendiri
Saat jenis bawaan tidak cocok, turunkan dari Error:
Dua hal yang perlu diingat: panggil super(message) agar Error dasarnya tersiapkan dengan benar, dan atur this.name agar log menampilkan label yang tepat. Field buatan sendiri seperti field memungkinkan pemanggil menanggapi jenis kegagalan tertentu tanpa mem-parsing string.
Berikutnya: Console dan DevTools
Mengenal jenis error baru separuh perjuangan. Separuh lainnya adalah membaca stack trace dan memeriksa state saat program berjalan. Devtools di browser (dan debugger di Node) mengubah "error-nya muncul dan aku tidak tahu kenapa" menjadi beberapa detik pemeriksaan. Itu topik berikutnya.
Pertanyaan yang sering diajukan
Apa saja jenis error bawaan di JavaScript?
JavaScript punya tujuh: Error (dasarnya), SyntaxError, ReferenceError, TypeError, RangeError, URIError, dan EvalError. Masing-masing adalah constructor yang menghasilkan objek error dengan property name, message, dan stack. Yang paling sering kamu temui adalah SyntaxError, ReferenceError, dan TypeError.
Apa bedanya SyntaxError dan TypeError?
SyntaxError berarti kodenya bukan JavaScript yang valid: engine bahkan tidak bisa mem-parsing-nya. TypeError berarti kodenya berhasil di-parse tetapi melakukan sesuatu yang tidak sah saat runtime, seperti memanggil sesuatu yang bukan fungsi atau membaca property dari null. Syntax error menghentikan seluruh script; type error hanya muncul saat baris yang bermasalah berjalan.
Kapan aku mendapat ReferenceError di JavaScript?
Saat kamu memakai nama yang belum dideklarasikan, atau mengakses variabel let/const di temporal dead zone-nya (sebelum deklarasinya berjalan). Salah ketik adalah penyebab paling umum: consoel.log(x) memunculkan ReferenceError: consoel is not defined. Cek ejaan dan scope terlebih dulu.
Bisakah aku membuat jenis error sendiri?
Bisa. Turunkan dari class Error bawaan: class ValidationError extends Error { }. Atur this.name di constructor agar log dan cabang catch bisa membedakannya. Class error buatan sendiri sangat berguna saat kegagalan yang berbeda butuh penanganan yang berbeda.