Apa praktik terbaik untuk penanganan kesalahan JavaScript?

137

Saya cari untuk mulai membuat saya JavaScript sedikit lebih bukti kesalahan, dan saya menemukan banyak dokumentasi tentang cara menggunakan try, catch, finally, dan throw, tapi aku tidak menemukan satu ton saran dari para ahli tentang kapan dan di mana untuk melempar kesalahan.

  • Apakah setiap kode harus dibungkus dengan try / catch?
  • Apakah ada lebih banyak nasihat seperti ini tentang kesalahan apa yang harus ditangkap?
  • Apakah ada kerugian untuk meningkatkan kesalahan alih-alih kode gagal diam-diam dalam produksi?
  • Ini telah disentuh pada SO sejauh implementasi, tetapi apakah kesalahan server-logging JS strategi yang efektif?
  • Ada hal lain yang harus saya ketahui, tentang menjebak kesalahan dalam aplikasi saya?

Saya juga sepenuhnya permainan untuk mendengar buku-buku yang memiliki bab besar atau penjelasan mendalam tentang penanganan kesalahan. JavaScript fasih menyentuh masalah ini, tetapi tidak terlalu menentukan atau berpendapat tentang masalah ini.

Terima kasih atas saran yang bisa Anda berikan!

Joshua Cody
sumber
Itu pasti tergantung pada seberapa spektakuler Anda gagal jika ada kesalahan dan volume pesan kesalahan yang mungkin terjadi. Anda tidak ingin gagal karena direktori logging kesalahan Anda sudah penuh sekarang kan? - Apakah kamu melihat di sini sama sekali? stackoverflow.com/search?q=error+logging+javascript
mplungjan
@plpljan pemahaman sendiri dan pencari masa depan. Mungkin ini adalah topik di mana meresepkan praktik terbaik tidak mungkin, tetapi setiap situasi sangat unik?
Joshua Cody
1
"Haruskah setiap bagian kode dibungkus dengan try / catch?" Tentu saja tidak. Ada banyak kode yang Anda tahu akan selalu berfungsi (dengan asumsi Anda mengujinya, tentu saja, tetapi titik try / catch bukanlah untuk menangkap atau mengabaikan kesalahan pengkodean). Hanya membungkus kode yang mungkin gagal beberapa waktu karena sesuatu di luar kendali, umumnya hal-hal seperti akses sumber daya, dll. Catatan: beberapa hal yang dapat gagal memiliki penanganan kesalahan bawaan, misalnya, saya tidak akan repot-repot mengkode Ajax dari awal ketika ada banyak perpustakaan yang melakukannya yang menangani masalah lintas-browser dan memungkinkan Anda menentukan fungsi penangan kesalahan.
nnnnnn
1
Ini adalah pertanyaan yang bagus Josh, +1. Ada banyak nasihat sintaksis di sekitar, tetapi seperti yang Anda katakan itu adalah bagian yang mudah. Disentuh dalam jawaban pertanyaan ini ( stackoverflow.com/questions/2825427/… ) di mana dijelaskan bahwa Pengecualian tidak seperti yang biasa digunakan di JS dan alasan diberikan.
whitneyland

Jawaban:

63

Satu set slide yang sangat menarik tentang Penanganan Kesalahan JavaScript Perusahaan dapat ditemukan di http://www.devhands.com/2008/10/javascript-error-handling-and-general-best-practices/

Singkatnya, ini merangkum:

  1. Anggap kode Anda akan gagal
  2. Kesalahan log ke server
  3. Anda, bukan browser, yang menangani kesalahan
  4. Identifikasi di mana kesalahan mungkin terjadi
  5. Lempar kesalahan Anda sendiri
  6. Bedakan kesalahan fatal versus non-fatal
  7. Berikan mode debug

Slide menjadi jauh lebih detail dan kemungkinan besar akan memberi Anda arahan.

MEMPERBARUI

Presentasi yang disebutkan di atas dapat ditemukan di sini: http://www.slideshare.net/nzakas/enterprise-javascript-error-handling-presentation

cdmdotnet
sumber
24
Tautan devhands rusak.
Ryan Gates
7
Bagi mereka yang membaca ini di 2017, saya berpendapat bahwa Anda tidak akan mendapatkan banyak nilai dari slide - ringkasan ini memberi Anda 90% dari informasi. Itu masih informasi yang berharga. Bersulang!
Philippe Hebert
29

Nicholas Zakas dari Yahoo! Fame berbicara tentang Enterprise Error Handling ( slide ) di Ajax Experience 2008, di mana dia mengusulkan sesuatu seperti ini:

function log(sev,msg) {
    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);
}

// usage
log(1, "Something bad happened.")

// Auto-log uncaught JS errors
window.onerror = function(msg, url, line) {
    log(1, msg);
    return true;
}

Setahun kemudian, Nicholas Zakas memposting pembaruan di blog-nya yang menyertakan pola cerdik untuk menyuntikkan kode penanganan kesalahan secara otomatis pada lingkungan produksi Anda (menggunakan pemrograman berorientasi aspek).

Ketika Anda mulai mencatat panggilan window.error, Anda akan melihat dua hal:

  1. Jika situs Anda cukup kompleks, Anda akan mencatat banyak kesalahan
  2. Anda akan melihat banyak pesan "window.error tidak berguna yang tidak terdefinisi: 0"

Mengurangi torrent entri log semudah menguji keparahan dan / atau nomor acak sebelum masuk ke server:

function log(sev,msg) {
    if (Math.random() > 0.1) return; // only log some errors

    var img = new Image();
    img.src = "log.php?sev=" +
        encodeURIComponent(sev) +
        "&msg=" + encodeURIComponent(msg);
}

Menangani "window.error yang tidak berguna dalam undefined: 0" kesalahan tergantung pada arsitektur situs Anda, tetapi dapat mencoba mengidentifikasi semua panggilan Ajax dan melemparkan pengecualian ketika sesuatu gagal (mungkin mengembalikan jejak stack menggunakan stacktrace.js ).

Jens Roland
sumber
67
Saya tahu ini adalah pertanyaan lama, tetapi menyarankan untuk mengabaikan beberapa kesalahan secara acak adalah salah satu ide terburuk yang pernah saya dengar.
jbabey
26
@ jbabey: Untuk situs kecil Anda benar, tetapi jika Anda menjalankan situs besar dengan 100.000 atau jutaan pengguna, Anda benar-benar tidak perlu membanjiri server Anda (atau internet) dengan permintaan logging yang berlebihan. Pada sistem yang cukup besar, setiap kesalahan nyata akan terjadi puluhan ribu kali sehari, jadi bentuk pembatasan ini berfungsi dengan baik. Idenya sebenarnya diterapkan di Facebook.
Jens Roland
1
Kesalahan logging saat dalam mode debugging sepertinya sama pentingnya dengan membatasi laporan kesalahan produksi, jadi orang mungkin mencatat bahwa solusi diperlukan untuk mengelola nilai yang membatasi ambang logging.
frattaro
2
@NickBull Saya merekayasa balik sekelompok modul JavaScript Facebook pada 2011-2012; di situlah saya menemukannya.
Jens Roland
1
@NickBull baru saja memeriksa file lama saya, masih memiliki ini. Saya menemukan trik ini dalam modul bootloader Facebook: if (global.logJSError) if (Math.random() < .01) logJSError('bootloader', {(memang diakui bahwa kode tidak membatasi semua kesalahan, hanya kelas kesalahan batas waktu tertentu)
Jens Roland
7

IHMO, Anda harus menggunakan penanganan kesalahan dalam javascript seperti yang Anda lakukan dalam beberapa bahasa lain (AFAIK: Python, Java).

Untuk keterbacaan yang lebih baik (dan mungkin kinerja yang lebih baik, meskipun saya tidak yakin itu memiliki dampak yang sangat besar), Anda harus menggunakan blok coba / tangkap sebagian besar pada kasus-kasus berikut:

  • Bagian dari kode yang ingin Anda bungkus adalah bagian kunci dari keseluruhan algoritma . Jika gagal, itu bisa:

    • buat kesalahan pada bagian selanjutnya dari kode (mis. karena var hilang ...)
    • membuat halaman tidak terlihat seperti yang diharapkan (berdampak pada konten atau css)
    • buat hasilnya tampak aneh bagi pengguna (berdampak pada perilaku kode)
  • Anda tahu bahwa kode yang Anda tulis tidak kompatibel dengan setiap browser

  • Anda merencanakan bahwa kode tersebut mungkin gagal (karena tidak ada cara lain untuk memeriksa apakah kode itu berfungsi jika ... maka ... blok)
  • Dan juga ketika Anda ingin men - debug tanpa mengganggu pengguna akhir

Akhirnya, pakar javascript mungkin memiliki elemen lain untuk diberikan.

2 sen saya ke kotak,

Salam,

Maks

JMax
sumber
1
"Bagian dari kode yang ingin Anda bungkus adalah bagian kunci dari keseluruhan algoritma" - mungkin tergantung pada bagaimana Anda ingin menangani kegagalan. Jika Anda tahu tidak ada cara untuk melanjutkan dengan algoritma setelah kegagalan, mungkin lebih baik untuk membungkus semuanya dalam mencoba / menangkap karena jika Anda mencoba / menangkap (misalnya) terkubur di dalam loop bersarang itu akan lebih merupakan hit kinerja . Di sisi lain, jika Anda dapat mengambil beberapa tindakan pengecualian dan melanjutkan dengan algoritme maka Anda akan memerlukan pengaturan try / catch yang lebih baik.
nnnnnn
5

Selain jawaban lain: satu hal penting adalah menggunakan data konteks yang tersedia di objek kesalahan JavaScript dan dalam window.onerrorparameter fungsi.

Hal-hal seperti stacktrace (errorObject.stack), nama file, nomor baris dan nomor kolom. Perhatikan bahwa setiap browser memiliki beberapa perbedaan ... jadi lakukan yang terbaik untuk mendapatkan kesalahan yang bagus.

Bahkan bisa ada masalah dengan objek konsol itu sendiri . Saya menggunakan fungsi window.onerror khusus terinspirasi oleh ini dan fungsi khusus untuk melacak objek kesalahan standar yang diberikan terinspirasi oleh kode ini .

Poin bagus lainnya adalah memasukkan versi aplikasi web Anda di dekat stacktrace (untuk menyalin dan menempelkan dengan cepat dan aman). Anda juga dapat menampilkan kesalahan lebih agresif (waspada ...) dalam mode pengembangan karena pengembang tidak akan terus-menerus memonitor konsol browser dan mungkin tidak melihat beberapa masalah.

Juga gunakan menghindari menggunakan throw 'My message', menggunakan throw new Error('My message'), Anda bahkan dapat memiliki kesalahan khusus, baca artikel ini .

Selalu tambahkan beberapa konteks ke kesalahan (versi, id objek, beberapa pesan khusus, ...) dan juga pastikan Anda membuat perbedaan antara kesalahan eksternal (beberapa data eksternal atau keadaan membuat sistem Anda gagal) dan kesalahan internal / pernyataan (sistem Anda sendiri kacau), baca tentang ' Desain berdasarkan kontrak '.

Ini panduannya .

Pikirkan juga tentang menggunakan penanganan kesalahan umum seperti pencegat lib dan kerangka kerja Anda:

Christophe Roussy
sumber