Tidak peduli seberapa hebatnya kita dalam pemograman, terkadang kodingan kita memiliki banyak eror. Mereka mungkin muncul dikarenakan kesalahan kita, input dari user yang tidak terduga, eror respon dari server, dan juga berbagai macam alasan lainnya.
Biasanya, sebuah kodingan/scrip “terhenti” (tiba-tiba berhenti) dikarenakan adanya eror, menampilkan erornya pada console.
Tapi terdapat sebuah sintaks try..catch yang memperbolehkan kita untuk “menangkap” hasil eror sehingga skrip bisa berjalan sesuai dengan arahan kita, dibanding hanya berhenti saja.
Sintaks “try…catch”
Sintaks try..catch membentuk dua bagian utama: pertama try, dan kemudian catch:
try {
// kodingan disini
} catch (err) {
// Penanganan jika eror
}
Mereka akan bekerja seperti ini:
- Pertama, kodingan pada
try {...}akan dijalankan. - Jika tidak terdapat eror, maka
catch(err)akan dihiraukan: prosesnya akan mencapai ujung bagiantrydan kemudian berlanjut, melewati bagiancatch. - Jika terdapat eror, maka bagian
tryakan berhenti berjalan, dan alur prosesnya akan berlanjut pada awal bagiancatch(err). Variabelerr(yang mana kita bisa ganti dengan nama apapun) akan mengandung eror objek dengan keterangan eror didalamnya.
Jadi, sebuah eror didalam bagian try {…} tidak akan memberhentikan kodingan tersebut – kita memiliki sebuah kesempatan untuk menanganinya pada bagian catch.
Mari kita lihat contoh lainnya.
-
Sebuah contoh tanpa eror: menampilkan
alert(1)dan(2):try { alert('Start of try runs'); // (1) <-- // ...tidak ada eror disini alert('End of try runs'); // (2) <-- } catch (err) { alert('Catch is ignored, because there are no errors'); // (3) } -
Sebuah contoh dengan eror: shows
(1)dan(3):try { alert('Start of try runs'); // (1) <-- lalala; // error, variable is not defined! alert('End of try (never reached)'); // (2) } catch (err) { alert(`Error has occurred!`); // (3) <-- }
try..catch hanya akan bekerja pada eror runtimeUntuk try..catch agar bekerja, kodingan tersebut harus bisa dijalankan. Dengan artian lain, itu harus dalam bahasa javascript yang valid.
Mereka tidak akan bekerja jika kodingan tersebut secara sintaks salah, sebagai contoh jika mereka memiliki kurung kurawal yang tidak sama:
try {
{{{{{{{{{{{{
} catch (err) {
alert("The engine can't understand this code, it's invalid");
}
Mesin Javascript pertama membaca kodingan tersebut, dan menjalankannya. eror yang terjadi pada saat proses pembacaan disebut sebagai eror “parse-time” dan tidak dapat dipulihkan (dari dalam kodingan tersebut). Itu dikarenakan mesin javascript tidak mengerti kodingan .
Jadi, try..catch hanya dapat menangani eror yang terjadi pada kodingan yang valid. eror demikian biasanya dinamakan sebagai “eror runtime” atau terkadang, “exceptions”.
try..catch bekerja secara sinkronisJika sebuah exception terjadi pada kodingan yang “terjadwal”, seperti pada setTimeout, maka try..catch tidak akan menangkapnya:
try {
setTimeout(function() {
noSuchVariable; // kodingan akan berhenti disini
}, 1000);
} catch (err) {
alert( "won't work" );
}
Itu dikarenakan fungsi tersebut dijalankan nanti, ketika mesin javascript telah meninggalkan bagian pada try..catch.
Untuk menangkap sebuah exception didalam sebuah fungsi yang terjadwal, try..catch harus terjadi didalam fungsi tersebut:
setTimeout(function() {
try {
noSuchVariable; // try..catch menangani eror tersebut!
} catch {
alert( "error is caught here!" );
}
}, 1000);
Eror Objek
Ketika sebuah eror terjadi, Javascript menghasilkan sebuah ojek yang berisikan keterangan terkait eror tersebut. Objek itu kemudian dilewatkan sebagai sebuah argumen pada bagian catch:
try {
// ...
} catch(err) { // <-- "error object", bisa menggunakan kata lain selain err
// ...
}
Untuk semua eror bawaan, eror objek memiliki dua properti utama:
name- Nama error. sebagai contoh, untuk variable yang belum terdefinisikan maka itu disebut
"ReferenceError". message- Pesan yang ada didalam eror tersebut.
Terdapat properti non-standard lainnya pada kebanyakan Ada properti non-standar lain yang tersedia di sebagian besar lingkungan. Salah satu yang paling banyak digunakan dan didukung ialah:
stack- Call stack saat ini: string dengan informasi tentang urutan panggilan bertingkat yang menyebabkan kesalahan. Digunakan untuk tujuan debugging.
Sebagai contoh:
try {
lalala; // error, variable is not defined!
} catch (err) {
alert(err.name); // ReferenceError
alert(err.message); // lalala is not defined
alert(err.stack); // ReferenceError: lalala is not defined at (...call stack)
// Can also show an error as a whole
// The error is converted to string as "name: message"
alert(err); // ReferenceError: lalala is not defined
}
“Catch” binding Opsional
Jika kita tidak butuh detail tentang eror, catch mungkin bisa menghilangkannya:
try {
// ...
} catch { // <-- tanpa (err)
// ...
}
Menggunakan “try…catch”
Mari kita telusuri contoh penggunaan nyata dari try..catch.
Seperti yang telah kita ketahui, Javascript mendukung method JSON.parse(str) yang membaca dari nilai JSON-encoded.
Biasanya digunakan untuk memecahkan kode data yang diterima melalui jaringan, dari server atau sumber lain.
Kita menerimanya dan memanggil JSON.parse seperti ini:
let json = '{"name":"John", "age": 30}'; // data dari server
let user = JSON.parse(json); // mengonversi representasi teks ke objek JS
// sekarang pengguna adalah objek dengan properti dari string
alert( user.name ); // John
alert( user.age ); // 30
Kalian dapat menemukan informasi lebih detail tentang JSON di bab <info: json>.
Jika format json salah,JSON.parse menghasilkan error, sehingga skrip “mati”.
Cukupkah kita puas dengan itu? Tentu saja tidak!
Dengan cara ini, jika ada yang salah dengan datanya, pengunjung tidak akan pernah mengetahuinya (kecuali mereka membuka konsol pengembang). Dan orang biasanya tidak suka ketika sesuatu “berhenti begitu saja” tanpa ada pesan kesalahan.
Mari gunakan try..catch untuk menangani kesalahan:
let json = "{ bad json }";
try {
let user = JSON.parse(json); // <-- ketika terjadi sebuah eror...
alert( user.name ); // tidak berjalan
} catch (err) {
// ...proses eksekusinya akan lompat kesini
alert( "Our apologies, the data has errors, we'll try to request it one more time." );
alert( err.name );
alert( err.message );
}
Di sini kita menggunakan blok catch hanya untuk menampilkan pesan, tetapi kita dapat melakukan lebih banyak lagi: mengirim permintaan jaringan baru, menyarankan alternatif kepada pengunjung, mengirim informasi tentang kesalahan ke fasilitas logging, …. Semuanya jauh lebih baik daripada sekedar mati.
Melontarkan eror kita sendiri
Bagaimana jika json secara sintaksis benar, tetapi tidak memiliki propertiname yang diperlukan?
Seperti ini:
let json = '{ "age": 30 }'; // data tidak lengkap
try {
let user = JSON.parse(json); // <-- tidak ada eror
alert( user.name ); // tidak ada nama!
} catch (err) {
alert( "doesn't execute" );
}
Di sini JSON.parse berjalan normal, tetapi tidak adanyanama sebenarnya merupakan eror bagi kita.
Untuk menyatukan penanganan error, kita akan menggunakan operator throw.
Operator “Throw”
Operator throw menghasilkan sebuah eror.
Sintaksnya adalah:
throw <error object>
Secara teknis, kita dapat menggunakan apapun sebagai eror objek.
Technically, we can use anything as an error object. Itu bahkan mungkin dengan data primitif, seperti angka atau string, lebih disarankan menggunakan objek, dan juga dengan properti name danmessage (agar tetap kompatibel dengan error bawaan).
JavaScript memiliki banyak konstruktor bawaan untuk standar eror: Error, SyntaxError,ReferenceError, TypeError dan lain-lain. Kita bisa menggunakannya untuk membuat eror objek juga.
Sintaksnya adalah:
let error = new Error(message);
// or
let error = new SyntaxError(message);
let error = new ReferenceError(message);
// ...
Untuk eror bawaan (bukan untuk objek lainnya, hanya untuk eror), properti name persis dengan nama konstruktornya. Dan pesan diambil dari argumennya.
Sebagai contoh: