Apa perbedaan antara `throw new Error` dan` throw someObject`?

378

Saya ingin menulis handler kesalahan umum yang akan menangkap kesalahan kustom yang dilemparkan dengan sengaja pada setiap contoh kode.

Ketika saya throw new Error('sample')suka dalam kode berikut

try {
    throw new Error({'hehe':'haha'});
    // throw new Error('hehe');
} catch(e) {
    alert(e);
    console.log(e);
}

Log menunjukkan di Firefox sebagai Error: [object Object]dan saya tidak dapat menguraikan objek.

Untuk yang kedua throwlog ditampilkan sebagai:Error: hehe

Sedangkan ketika saya melakukannya

try {
    throw ({'hehe':'haha'});
} catch(e) {
    alert(e);
    console.log(e);
}

konsol ditampilkan sebagai: Object { hehe="haha"}di mana saya dapat mengakses properti kesalahan.

Apa bedanya?

Apakah perbedaannya seperti yang terlihat dalam kode? Seperti string akan hanya diteruskan sebagai string dan objek sebagai objek tetapi sintaks akan berbeda?

Saya belum menjelajahi objek melempar kesalahan ... Saya hanya melakukan melempar string.

Apakah ada cara lain selain dua metode yang disebutkan di atas?

Jayapal Chandran
sumber
6
Masalah dengan melempar Kesalahan baru ({prop: val}) adalah itu bukan konstruksi Kesalahan yang valid. Kesalahan telah diketahui properti seperti yang dibahas oleh Hemant.
Grantwparks

Jawaban:

216

Berikut adalah penjelasan yang baik tentang objek Kesalahan dan melemparkan kesalahan Anda sendiri

Objek Kesalahan

Apa yang bisa kita ekstrak darinya jika terjadi kesalahan? Objek Galat di semua browser mendukung dua properti berikut:

  • nama: Nama kesalahan, atau lebih khusus, nama fungsi konstruktor milik kesalahan.

  • pesan: Deskripsi kesalahan, dengan deskripsi ini bervariasi tergantung pada browser.

Enam nilai yang mungkin dapat dikembalikan oleh properti nama, yang sebagaimana disebutkan sesuai dengan nama-nama konstruktor kesalahan. Mereka:

Error Name          Description

EvalError           An error in the eval() function has occurred.

RangeError          Out of range number value has occurred.

ReferenceError      An illegal reference has occurred.

SyntaxError         A syntax error within code inside the eval() function has occurred.
                    All other syntax errors are not caught by try/catch/finally, and will
                    trigger the default browser error message associated with the error. 
                    To catch actual syntax errors, you may use the onerror event.

TypeError           An error in the expected variable type has occurred.

URIError            An error when encoding or decoding the URI has occurred 
                   (ie: when calling encodeURI()).

Melempar kesalahan Anda sendiri (pengecualian)

Alih-alih menunggu salah satu dari 6 jenis kesalahan terjadi sebelum kontrol secara otomatis ditransfer dari blok coba ke blok tangkap, Anda juga dapat secara eksplisit melempar pengecualian Anda sendiri untuk memaksa itu terjadi atas permintaan. Ini bagus untuk membuat definisi Anda sendiri tentang apa kesalahan itu dan kapan kontrol harus ditransfer untuk menangkap.

Hemant Metalia
sumber
4
Oh ya. ini adalah salah satu hal baik yang saya lewatkan sebelum menanyakan pertanyaan ini. toh para pengguna yang mencari informasi terkait ini akan dihapus. Sekarang saya jelas tentang apa itu. :) Terima kasih. saya akan kembali untuk memberikan suara dalam beberapa hari.
Jayapal Chandran
185
Bahkan belum menjawab pertanyaan, namun jawaban yang paling banyak dipilih?
user9993
@ user9993 Pengguna yang ditanya pertanyaan sedang mencari pemahaman terperinci sesuai obrolan pada waktu itu, sehingga jawaban telah disediakan dan bermanfaat bagi pengguna. itulah alasan untuk suara yang diterima dan paling banyak.
Hemant Metalia
5
@HemantMetalia Tapi dia benar, jawabannya tidak menunjukkan sedikit pun upaya untuk menjawab pertanyaan OP seperti yang dinyatakan. Jika beberapa jawaban yang sangat berbeda dalam obrolan dijawab yang seharusnya tetap ada dalam obrolan, di sini pertanyaan dan jawaban tidak memiliki hubungan logis apa pun.
Mörre
Dan untuk menjawab pertanyaan awal, itu tidak masalah untuk Javascript. Namun, Error(dan subclass) digunakan oleh konvensi. Mereka juga secara default menyediakan properti stack, meskipun itu bisa secara manual ditambahkan ke yang lain. Jadi kebanyakan konvensi, aliran program tidak terpengaruh oleh apa yang Anda lemparkan, hanya saja Anda yang throwterpenting. Anda bisa throw "grandmother down the stairs";dan itu akan bekerja sama, kecuali bahwa tidak akan ada jejak stack terlampir dan fungsi penanganan kesalahan, reporter, debuggers harapkan Error, atau properti yang menyertainya, lebih tepatnya.
Mörre
104

lempar "I'm Evil"

throwakan mengakhiri eksekusi lebih lanjut & mengekspos string pesan pada catch the error.

try {
  throw "I'm Evil"
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e); //I'm Evil
}

Konsol setelah lemparan tidak akan pernah tercapai karena penghentian.


throw new Error ("Aku sangat manis")

throw new Errormemperlihatkan peristiwa kesalahan dengan dua nama params & pesan . Ini juga menghentikan eksekusi lebih lanjut

try {
  throw new Error("I'm Evil")
  console.log("You'll never reach to me", 123465)
} catch (e) {
  console.log(e.name, e.message); //Error, I'm Evil
}

Nishchit Dhanani
sumber
16
bagaimana dengan perbedaan antara "throw Error ('apapun')" dan "throw Error baru ('apa pun')" - keduanya bekerja.
joedotnot
9
Kesalahan fungsional, Kesalahan baru adalah konstruktor. keduanya bekerja sama developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
5
@NishchitDhanani Saya merasa aneh bahwa komentar yang tidak dapat dipahami dan salah seperti itu mendapat upvotes. Baik "Kesalahan fungsional", maupun "Kesalahan baru adalah konstruktor" tidak masuk akal sama sekali dan / atau salah. Dalam konteks itu tidak jelas apa sebenarnya tautan yang seharusnya "dibuktikan". Ini halaman MDN untuk Error, oke, di mana koneksi ke komentar? Separuh orang yang berkomentar dan menjawab pertanyaan OP seharusnya tetap diam.
Mörre
@ Mörre Lihat bagian ini Used as a functiondari tautan ini ... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Nishchit Dhanani
Oke, saya mengerti. Itu sebuah fungsi .
Nishchit Dhanani
73

Artikel berikut mungkin masuk ke beberapa lebih detail untuk yang merupakan pilihan yang lebih baik; throw 'An error'atau throw new Error('An error'):

http://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

Ini menunjukkan bahwa yang terakhir ( new Error()) lebih dapat diandalkan, karena browser seperti Internet Explorer dan Safari (tidak yakin versi) tidak benar melaporkan pesan saat menggunakan yang pertama.

Melakukannya akan menyebabkan kesalahan untuk dilemparkan, tetapi tidak semua browser merespons seperti yang Anda harapkan. Firefox, Opera, dan Chrome masing-masing menampilkan pesan "pengecualian tanpa tertangkap" dan kemudian memasukkan string pesan. Safari dan Internet Explorer hanya melemparkan kesalahan "pengecualian tanpa tertangkap" dan tidak memberikan string pesan sama sekali. Jelas, ini suboptimal dari sudut pandang debugging.

Ed.
sumber
36

Anda pertama kali menyebutkan kode ini:

throw new Error('sample')

dan kemudian dalam contoh pertama Anda, Anda menulis:

throw new Error({'hehe':'haha'}) 

Objek Kesalahan pertama benar-benar akan berfungsi, karena mengharapkan nilai string, dalam hal ini 'sampel'. Yang kedua tidak akan karena Anda mencoba untuk melewati objek, dan itu mengharapkan string.

Objek kesalahan akan memiliki properti "pesan", yang akan menjadi 'sampel'.

IonicBurger
sumber
12
Yang kedua berhasil, hanya saja tidak dengan cara yang sangat berguna. Ini mengeksekusi toString()metode pada objek yang dilewatkan, menghasilkan [object Object]kesalahan (seperti Op menulis).
cjn
15

Anda bisa throwsebagai objek

throw ({message: 'This Failed'})

lalu misalnya di try/catch

try {
//
} catch(e) {
    console.log(e); //{message: 'This Failed'}
    console.log(e.message); //This Failed
}

atau hanya melempar kesalahan string

throw ('Your error')

try {
//
} catch(e) {
    console.log(e); //Your error
}

throw new Error //only accept a string
Mbanda
sumber
15

The Errorkonstruktor digunakan untuk membuat suatu objek error. Objek kesalahan dilemparkan ketika terjadi kesalahan runtime. Objek Kesalahan juga dapat digunakan sebagai objek dasar untuk pengecualian yang ditentukan pengguna.

Kesalahan yang Ditentukan Pengguna dilemparkan melalui throwpernyataan. kontrol program akan diteruskan ke catchblok pertama di tumpukan panggilan.

Perbedaan antara melempar kesalahan dengan dan tanpa objek Kesalahan:


throw {'hehe':'haha'};

Dalam chrome devtools terlihat seperti ini:

masukkan deskripsi gambar di sini

Chrome memberi tahu kami bahwa kami memiliki kesalahan yang tidak tertangkap yang hanya merupakan objek JS. Objek itu sendiri dapat memiliki informasi mengenai kesalahan tersebut tetapi kami masih belum tahu dari mana asalnya. Tidak terlalu berguna ketika kita mengerjakan kode kita dan men-debug-nya.


throw new Error({'hehe':'haha'}); 

Dalam chrome devtools terlihat seperti ini:

masukkan deskripsi gambar di sini

Kesalahan yang dilempar dengan objek Kesalahan memberi kami jejak stack saat kami memperluasnya. Ini memberi kami informasi berharga dari mana kesalahan itu berasal tepatnya yang seringkali merupakan informasi berharga ketika men-debug kode Anda. Perhatikan lebih lanjut bahwa kesalahan mengatakan [object Object], ini karena Errorkonstruktor mengharapkan string pesan sebagai argumen pertama. Ketika menerima objek, ia akan memaksanya menjadi string.

Willem van der Veen
sumber
2

Bereaksi perilaku

Terlepas dari sisa jawaban, saya ingin menunjukkan satu perbedaan dalam Bereaksi.

Jika saya melempar new Error()dan saya dalam mode pengembangan, saya akan mendapatkan layar kesalahan dan log konsol. Jika saya melempar string literal, saya hanya akan melihatnya di konsol dan mungkin melewatkannya, jika saya tidak menonton log konsol.

Contoh

Melemparkan kesalahan log ke konsol dan menunjukkan layar kesalahan saat dalam mode pengembangan (layar tidak akan terlihat dalam produksi).

throw new Error("The application could not authenticate.");

Layar kesalahan bereaksi

Sedangkan kode berikut hanya masuk ke konsol:

throw "The application could not authenticate.";
El Mac
sumber