Mengapa banyak pesan pengecualian tidak mengandung detail yang berguna?

220

Tampaknya ada sejumlah kesepakatan bahwa pesan pengecualian harus berisi perincian yang bermanfaat .

Mengapa banyak pengecualian umum dari komponen sistem tidak mengandung detail yang berguna?

Beberapa contoh:

  • NET Listakses indeks ArgumentOutOfRangeExceptiontidak tidak memberitahu saya nilai indeks yang diadili dan tidak sah, juga tidak memberitahu saya rentang diperbolehkan.
  • Pada dasarnya semua pesan pengecualian dari pustaka standar MSVC C ++ sama sekali tidak berguna (dengan nada yang sama seperti di atas).
  • Pengecualian Oracle dalam .NET, memberi tahu Anda (diparafrasekan) "TABEL ATAU LIHAT tidak ditemukan", tetapi tidak yang mana .

Jadi, bagi saya tampaknya sebagian besar pesan pengecualian tidak berisi rincian yang cukup untuk berguna. Apakah harapan saya di luar batas? Apakah saya menggunakan pengecualian yang salah sehingga saya perhatikan ini? Atau mungkin kesan saya salah: mayoritas pengecualian benar - benar memberikan detail yang berguna?

Martin Ba
sumber
59
Perlu dicatat bahwa dari sisi profesional keamanan, "pesan kesalahan tidak boleh berisi rincian tentang internal sistem" adalah aturan praktis.
Telastyn
118
@ Telastyn: Hanya jika sistem Anda terbuka untuk penyerang. Jika Anda menjalankan server Web, misalnya, Anda ingin menyajikan pesan kesalahan ringan kepada pengguna akhir, tetapi Anda masih ingin pesan kesalahan yang sangat terperinci untuk dicatat di akhir Anda. Dan pada perangkat lunak sisi klien, di mana pengguna bukan penyerang, Anda pasti ingin pesan kesalahan sedetail mungkin, sehingga ketika terjadi kesalahan dan Anda dikirim laporan bug, Anda memiliki informasi sebanyak mungkin untuk bekerja mungkin, karena banyak kali itu saja yang Anda dapatkan.
Mason Wheeler
9
@Snowman: Apa yang tidak dapat diakses pengguna jika itu perangkat lunak sisi klien? Pemilik mesin memiliki mesin dan bisa mendapatkan apa saja.
Mason Wheeler
6
Selalu ada beberapa info tambahan yang ingin Anda miliki. Saya menemukan pesan yang Anda berikan sebagai contoh cukup bagus. Anda dapat men-debug masalah dengan mereka. Jauh lebih baik daripada "kesalahan 0x80001234" (contoh terinspirasi oleh Pembaruan Windows).
usr

Jawaban:

204

Pengecualian tidak mengandung perincian yang berguna karena konsep pengecualian belum cukup matang dalam disiplin rekayasa perangkat lunak, sehingga banyak programmer tidak memahaminya sepenuhnya, dan oleh karena itu mereka tidak memperlakukannya dengan baik.

Ya, IndexOutOfRangeExceptionharus berisi indeks tepat yang berada di luar jangkauan, serta kisaran yang valid pada saat dilempar, dan itu hina atas nama pencipta runtime .NET yang tidak. Ya, table or view not foundpengecualian Oracle harus berisi nama tabel atau tampilan yang tidak ditemukan, dan lagi, fakta bahwa itu tidak dapat dihina atas nama siapa pun yang bertanggung jawab untuk ini.

Sebagian besar, kebingungan berasal dari ide asli yang salah arah bahwa pengecualian harus mengandung pesan yang dapat dibaca manusia, yang pada gilirannya berasal dari kurangnya pemahaman tentang apa yang dimaksud dengan pengecualian, sehingga merupakan lingkaran setan.

Karena orang berpikir bahwa pengecualian harus mengandung pesan yang dapat dibaca manusia, mereka percaya bahwa informasi apa pun yang dibawa oleh pengecualian juga harus diformat ke dalam pesan yang dapat dibaca manusia, dan kemudian mereka bosan untuk menulis semua pesan yang dapat dibaca manusia- membuat kode, atau mereka takut melakukan hal itu akan membocorkan informasi yang tidak disarankan kepada mata yang memandangi pesan itu. (Masalah keamanan disebutkan oleh jawaban lain.)

Tetapi kebenaran dari masalah ini adalah bahwa mereka tidak perlu khawatir tentang itu karena pengecualian tidak boleh mengandung pesan yang bisa dibaca manusia. Pengecualian adalah hal-hal yang hanya harus dilihat dan / atau ditangani oleh programmer. Jika ada kebutuhan untuk menyajikan informasi kegagalan kepada pengguna, itu harus dilakukan pada tingkat yang sangat tinggi, dengan cara yang canggih, dan dalam bahasa pengguna, yang, secara statistik, tidak mungkin berbahasa Inggris.

Jadi, bagi kita programmer, "pesan" pengecualian adalah nama kelas pengecualian , dan apa pun informasi lain yang berkaitan dengan pengecualian harus disalin ke variabel anggota (terakhir / hanya baca) dari objek pengecualian. Lebih disukai, setiap hal dapat dibayangkan. Dengan cara ini, tidak ada pesan yang perlu (atau harus) dihasilkan, dan karenanya tidak ada mata yang mengintip yang bisa melihatnya.

Untuk mengatasi kekhawatiran yang diungkapkan oleh Thomas Owens dalam komentar di bawah:

Ya, tentu saja, pada tingkat tertentu, Anda akan membuat pesan log tentang pengecualian. Tapi Anda sudah melihat masalah dengan apa yang Anda katakan: di satu sisi, pesan log pengecualian tanpa jejak tumpukan tidak berguna, tetapi di sisi lain, Anda tidak ingin membiarkan pengguna melihat seluruh jejak jejak pengecualian. Sekali lagi, masalah kita di sini adalah bahwa perspektif kita condong oleh praktik tradisional. File log secara tradisional dibuat dalam teks biasa, yang mungkin baik-baik saja ketika disiplin kita masih dalam masa pertumbuhan, tetapi mungkin tidak lagi: jika ada masalah keamanan, maka file log harus berupa biner dan / atau dienkripsi.

Apakah biner atau teks biasa, file log harus dianggap sebagai aliran ke mana aplikasi membuat serial informasi debug. Aliran seperti itu hanya untuk mata programmer, dan tugas menghasilkan informasi debug untuk pengecualian harus sesederhana serialisasi pengecualian ke dalam stream log debug. Dengan cara ini, dengan melihat log Anda bisa melihat nama kelas pengecualian, (yang, seperti telah saya sebutkan, adalah untuk semua tujuan praktis "pesan",) masing-masing variabel anggota pengecualian yang menggambarkan segala sesuatu yang berkaitan - dan-praktis-untuk-memasukkan-dalam-log, dan seluruh jejak tumpukan. Perhatikan bagaimana pemformatan pesan pengecualian yang dapat dibaca manusia jelas hilang dari proses ini.

PS

Beberapa pemikiran saya mengenai hal ini dapat ditemukan dalam jawaban ini: Cara menulis pesan pengecualian yang baik

PPS

Tampaknya banyak orang dicentang oleh saran saya tentang file log biner, jadi saya mengubah jawaban sekali lagi untuk membuatnya lebih jelas bahwa apa yang saya sarankan di sini bukanlah bahwa file log harus biner, tetapi itu file log mungkin biner, jika perlu.

Mike Nakis
sumber
4
Saya telah melihat beberapa kelas pengecualian di .NET Framework, dan ternyata ada banyak peluang untuk menambahkan informasi seperti ini secara terprogram. Jadi saya kira pertanyaannya adalah "mengapa mereka tidak melakukannya." Namun +1 untuk keseluruhan hal yang "dapat dibaca manusia".
Robert Harvey
7
Saya tidak setuju bahwa pengecualian tidak boleh mengandung komponen yang dapat dibaca manusia. Pada tingkat tertentu, Anda mungkin ingin membuat pesan log tentang pengecualian. Saya berpendapat bahwa logging jejak stack ke file log yang dapat dibaca pengguna mengekspos detail implementasi yang Anda tidak ingin mengekspos, sehingga pesan yang dapat dibaca manusia harus dicatat. Ketika disajikan dengan file log yang mengandung kesalahan, pengembang harus memiliki titik awal untuk memulai proses debug dan dapat memaksa pengecualian terjadi. Komponen yang dapat dibaca manusia harus dirinci secara tepat tanpa memberikan implementasi.
Thomas Owens
44
jadi programmer itu bukan manusia? Melihat rekan-rekan saya ini mengkonfirmasi beberapa kecurigaan yang saya miliki untuk beberapa waktu ...
gbjbaanb
51
Sekali lagi, tidak ada yang salah dengan membiarkan pengguna melihat seluruh jejak tumpukan , asalkan perangkat lunaknya adalah sisi klien. Setiap proyek perangkat lunak profesional yang pernah saya kerjakan, dan sebagian besar yang amatir juga, berisi sistem logging yang akan menghasilkan dump kesalahan penuh ketika pengecualian tidak ditangani dinaikkan, termasuk jejak tumpukan penuh dari semua utas yang saat ini berjalan di proses. Dan pengguna dapat (terkesiap, oh horor!) Melihatnya kapan saja dia mau, karena itu diperlukan (tidak hanya berguna, tetapi diperlukan ) untuk mengirim pesan kesalahan kembali kepada kami! Apa yang salah dengan itu?
Mason Wheeler
13
Saya juga tidak yakin sehubungan dengan file log biner saja . Terutama karena pengalaman saya dengan systemd. Alat khusus untuk melihat log ini cukup membingungkan dan tampaknya telah dirancang oleh komite monyet Shakespeare. Pertimbangkan bahwa, untuk aplikasi web, orang pertama yang melihat pengecualian Anda sering kali adalah sysadmin , dan ia akan ingin menentukan apakah itu sesuatu yang perlu ia perbaiki (mis. Disk kehabisan ruang) atau mengirimkan kembali untuk para pengembang.
Michael Hampton
46

Mengapa banyak pengecualian umum dari komponen sistem tidak mengandung detail yang berguna?

Dalam pengalaman saya, ada sejumlah alasan bahwa pengecualian tidak mengandung informasi yang berguna. Saya berharap bahwa alasan semacam ini juga berlaku untuk komponen sistem - tetapi saya tidak tahu pasti.

  • Orang yang fokus pada keamanan melihat pengecualian sebagai sumber kebocoran informasi ( misalnya ). Karena perilaku default pengecualian adalah untuk menampilkan informasi itu kepada pengguna, pemrogram terkadang melakukan kesalahan.
  • Dalam C ++, saya pernah mendengar argumen menentang mengalokasikan memori di catch block (di mana setidaknya beberapa konteks untuk membuat pesan yang baik terletak). Alokasi itu sulit dikelola, dan lebih buruk lagi, dapat menyebabkan pengecualian kehabisan memori di sana - sering membuat aplikasi Anda macet atau memori bocor. Sulit untuk memformat pengecualian dengan baik tanpa mengalokasikan memori, dan praktik itu mungkin telah bermigrasi antar bahasa seperti yang dilakukan pemrogram.
  • Mereka tidak tahu. Maksudku, ada yang skenario di mana kode memiliki tidak tahu apa yang salah. Jika kodenya tidak tahu - tidak bisa memberi tahu Anda.
  • Saya telah bekerja di tempat-tempat di mana masalah pelokalan mencegah menempatkan string hanya dalam bahasa Inggris ke dalam sistem - bahkan untuk pengecualian yang hanya akan dibaca oleh staf pendukung berbahasa Inggris.
  • Di beberapa tempat, saya telah melihat pengecualian menggunakan lebih banyak seperti menegaskan. Mereka ada di sana untuk memberikan pesan yang jelas dan keras selama pengembangan bahwa sesuatu tidak dilakukan, atau perubahan telah dilakukan di satu tempat, tetapi tidak di tempat lain. Ini seringkali cukup unik sehingga pesan yang baik akan diduplikasi atau hanya membingungkan.
  • Orang malas, programmer lebih dari kebanyakan. Kita menghabiskan waktu jauh lebih sedikit di jalan luar biasa daripada jalan bahagia, dan ini adalah efek samping.

Apakah harapan saya di luar batas? Apakah saya menggunakan Pengecualian yang salah sehingga saya menyadari hal ini?

Agak? Maksud saya, pengecualian harus memiliki pesan yang bagus, tetapi mereka juga pengecualian . Anda harus menghabiskan waktu merancang kode untuk menghindari kondisi luar biasa, atau menulis kode untuk menangani kondisi luar biasa (mengabaikan pesan), tidak menggunakannya sebagai semacam mekanisme umpan balik interaktif saat pengkodean. Tidak dapat dihindari untuk menggunakannya untuk tujuan debugging, tetapi dalam sebagian besar situasi yang harus dijaga agar tetap minimum. Bahwa Anda memperhatikan masalah ini membuat saya khawatir bahwa Anda tidak melakukan pekerjaan yang cukup baik untuk mencegah mereka.

Telastyn
sumber
Saya sadar ini telah ditandai sebagai C tetapi saya harus menambahkan bahwa paragraf terakhir Anda tidak berlaku untuk semua bahasa karena beberapa dapat (benar atau salah) sangat bergantung pada penanganan dan pelaporan kesalahan berbasis pengecualian .
Lilienthal
1
@ Lilienthal - seperti? Tidak ada bahasa yang saya sangat kenal melakukan hal semacam itu secara teratur.
Telastyn
1
Saya pikir jawaban ini memiliki banyak konten yang bagus, tetapi ia menghindari mengatakan intinya, yaitu "Mereka seharusnya."
djechlin
3
Terima kasih. Kekhawatiran Anda tidak berdasar (saya harap :-). Tetapi setiap kali saya menghabiskan satu menit ekstra untuk melacak apa yang salah dalam Tes Unit atau menghabiskan waktu ekstra menganalisis kode karena file log kurang info, saya agak jengkel dengan kebosanan yang dapat dihindari dari beberapa pesan :-)
Martin Ba
@Telastyn ABAP milik SAP memiliki konstruksi kelas pengecualian yang dapat berisi pesan, yang pada dasarnya adalah objek yang secara khusus dimaksudkan untuk melaporkan keadaan program (sukses, kegagalan, peringatan) kepada pengguna bersama dengan pesan dinamis (multi-bahasa). Saya akui saya tidak tahu seberapa luas hal semacam ini, atau jika itu didorong dalam bahasa itu mungkin, tetapi setidaknya ada satu di mana itu (sayangnya) praktik umum.
Lilienthal
12

Saya tidak memiliki kelebihan pengalaman C #, atau C ++ secara khusus, tetapi saya dapat memberitahu Anda ini - pengecualian yang ditulis pengembang 9 dari 10 kali lebih berguna daripada pengecualian umum yang pernah Anda temukan, titik.

Idealnya ya, pengecualian umum akan mengarahkan Anda ke persis mengapa kesalahan terjadi dan Anda akan dapat memperbaikinya dengan mudah - tetapi secara realistis, dalam aplikasi besar dengan beberapa kelas yang dapat melempar berbagai macam pengecualian, atau sama jenis pengecualian, itu selalu lebih berharga untuk menulis output Anda sendiri untuk kesalahan kembali daripada mengandalkan pesan default.

Begitulah seharusnya, karena sebagaimana banyak orang tunjukkan, beberapa aplikasi tidak ingin melemparkan pesan kesalahan yang mereka tidak ingin dilihat oleh pengguna, karena alasan keamanan atau untuk menghindari membingungkan mereka.

Sebagai gantinya, Anda harus mengantisipasi dalam desain Anda apa jenis kesalahan yang mungkin dilemparkan ke dalam aplikasi Anda (dan akan selalu ada kesalahan) dan menulis pesan-pesan yang menangkap kesalahan yang membantu Anda mengidentifikasi masalah.

Ini tidak akan selalu membantu Anda - karena Anda tidak dapat selalu mengantisipasi pesan kesalahan apa yang akan berguna - tetapi ini adalah langkah pertama untuk memahami aplikasi Anda sendiri dengan lebih baik dalam jangka panjang.

Zibbobz
sumber
7

Pertanyaannya adalah secara khusus menanyakan mengapa begitu banyak pengecualian yang dilemparkan oleh "komponen sistem" (alias kelas pustaka standar) tidak mengandung detail yang berguna.

Sayangnya, sebagian besar pengembang tidak menulis komponen inti di perpustakaan standar, juga tidak ada dokumen desain terperinci atau alasan desain lainnya yang harus dipublikasikan. Dengan kata lain, kita mungkin tidak pernah tahu pasti.

Namun, ada dua poin utama yang perlu diingat mengapa informasi pengecualian terperinci mungkin tidak diinginkan atau penting:

  1. Pengecualian dapat digunakan dengan memanggil kode dengan cara apa pun: perpustakaan standar tidak dapat menempatkan batasan tentang bagaimana pengecualian digunakan. Secara khusus, ini dapat ditampilkan kepada pengguna. Pertimbangkan indeks array di luar batas: ini dapat memberikan informasi yang berguna bagi penyerang. Perancang bahasa tidak tahu bagaimana aplikasi akan menggunakan pengecualian yang dilemparkan atau bahkan apa jenis aplikasi itu (misalnya aplikasi web atau desktop), sehingga meninggalkan informasi mungkin lebih aman dari perspektif keamanan.

  2. Pengecualian tidak boleh ditampilkan kepada pengguna. Sebagai gantinya, tampilkan pesan kesalahan yang ramah dan catat pengecualian ke lokasi yang tidak dapat diakses oleh penyerang (jika ada). Setelah kesalahan diidentifikasi, pengembang harus melakukan debug melalui kode, memeriksa frame stack dan jalur logika. Pada titik ini, pengembang memiliki lebih banyak informasi daripada yang bisa diharapkan oleh pengecualian.


sumber
3
1. Berdasarkan kriteria ini, nampaknya relatif sewenang-wenang apa informasi itu ("Indeks di luar jangkauan", tumpukan jejak) dan tidak ditampilkan (nilai indeks). 2. Debugging berpotensi menjadi jauh lebih cepat dan lebih mudah ketika nilai-nilai dinamis yang relevan diketahui. Misalnya, sering kali langsung memberi tahu Anda apakah masalahnya adalah input sampah ke bagian kode yang gagal, atau kode yang gagal menangani input yang benar
Ben Aaronson
@ BenAaronson pada identitas / kelas pengecualian memberitahu kita jenis kesalahan. Maksud saya adalah detail mungkin dihilangkan (yaitu nilai spesifik apa yang menyebabkan kesalahan) untuk keamanan. Nilai itu mungkin dapat dilacak kembali ke input pengguna, mengungkapkan informasi kepada penyerang.
@Snowman Saya hampir tidak berpikir keamanan adalah pertimbangan ketika jejak stack penuh tersedia, dan nomor indeks tidak. Tentu saya mengerti penyerang mencari buffer overflow, tetapi banyak pengecualian juga meninggalkan data yang cukup aman (mis. Tabel Oracle tidak ditemukan)
gbjbaanb
@ gbjbaanb yang bilang kita harus menunjukkan jejak stack penuh ke pengguna?
1
Terima kasih telah berbagi wawasan itu. Secara pribadi, saya tidak setuju dan menganggap argumen keamanan itu adalah kesalahan total, tetapi mungkin ini merupakan alasan.
Martin Ba
4

Pertama, izinkan saya memecahkan gelembung dengan mengatakan bahkan jika pesan diag dimuat dengan informasi yang membawa Anda ke baris kode dan perintah sub yang tepat dalam 4 detik, kemungkinan para pengguna tidak akan pernah menuliskannya atau menyampaikannya kepada orang-orang yang mendukung dan Anda akan diberitahu "Yah itu mengatakan sesuatu tentang pelanggaran ... Saya tidak tahu itu terlihat rumit!"

Saya telah menulis perangkat lunak dan mendukung hasil perangkat lunak orang lain selama lebih dari 30 tahun sekarang, dan secara pribadi, kualitas pesan pengecualian saat ini hampir tidak ada hubungannya dengan keamanan, terlepas dari bagaimana hasil akhirnya terjadi sesuai dengan model mereka. alam semesta, yang lebih berkaitan dengan fakta bahwa begitu banyak di industri kami yang awalnya belajar sendiri, dan mereka tidak pernah memasukkan pelajaran dalam komunikasi. Mungkin jika kita MEMINDAHKAN semua coders baru ke posisi pemeliharaan selama beberapa tahun di mana mereka harus berurusan dengan mencari tahu apa yang salah, mereka akan memahami pentingnya setidaknya beberapa bentuk presisi.

Baru-baru ini dalam aplikasi yang sedang dibangun kembali, keputusan dibuat bahwa kode kembali akan jatuh ke dalam salah satu dari tiga kelompok:

  • 0 hingga 9 akan berhasil melalui kesuksesan dengan informasi tambahan.
  • 10 hingga 99 akan menjadi kesalahan yang tidak fatal (dapat dipulihkan), dan
  • 101 hingga 255 akan menjadi kesalahan fatal.

(100 karena beberapa alasan ditinggalkan)

Dalam alur kerja tertentu, pemikiran kami digunakan kembali atau kode generik akan menggunakan pengembalian generik (> 199) untuk kesalahan fatal, membuat kami memiliki 100 kesalahan fatal yang mungkin untuk alur kerja. Dengan sedikit membedakan data dalam pesan, kesalahan seperti file tidak ditemukan semua bisa menggunakan kode yang sama dan membedakan dengan pesan.

Ketika kode kembali dari kontraktor, Anda tidak akan percaya kejutan kami ketika hampir SETIAP KESALAHAN FATAL TUNGGAL adalah kode pengembalian 101.

Semua yang dianggap saya pikir jawaban untuk pertanyaan Anda adalah pesan-pesan itu sangat tidak berarti karena ketika awalnya dibuat, mereka harus menjadi penampung yang tidak ada yang kembali. Akhirnya orang menemukan cara untuk memperbaiki masalah bukan karena pesan tetapi DISPITE mereka.

Sejak saat itu, orang-orang yang belajar mandiri tidak pernah memiliki contoh yang baik tentang apa yang harus dikandung pengecualian. Tambahkan ke bahwa lebih banyak pengguna tidak membaca pesan, apalagi mencoba untuk meneruskannya ke dukungan (Saya telah melihat pesan kesalahan yang terpotong-potong oleh yang digunakan yang kemudian dihapus sebelum dikirim dengan komentar kemudian bahwa itu sepertinya banyak informasi dan saya tidak mungkin menginginkan semuanya, jadi mereka secara acak menghapus banyak informasi.

Dan mari kita hadapi itu, dengan terlalu banyak (tidak semua tetapi terlalu banyak) dari generasi coders berikutnya, jika itu lebih banyak pekerjaan dan tidak menambahkan flash, hanya saja tidak layak ...

Catatan terakhir: Jika pesan kesalahan menyertakan kode kesalahan / pengembalian, bagi saya tampaknya di suatu tempat dalam modul yang dieksekusi harus ada baris yang bertuliskan "jika kondisi mengembalikan nilai-kode" dan kondisi harus memberi tahu Anda mengapa kode pengembalian terjadi. Ini sepertinya pendekatan logis yang sederhana, tetapi bagi saya, coba saja agar Microsoft memberi tahu Anda apa yang terjadi ketika pemutakhiran windows gagal pada KODE 80241013 atau pengidentifikasi unik lainnya. Agak sedih, bukan?

Randy
sumber
8
"... kamu tidak akan percaya kejutan kami ketika hampir SETIAP KESALAHAN FATAL TUNGGAL adalah kode pengembalian 101." Kamu benar. Saya tidak akan percaya Anda terkejut ketika kontraktor mengikuti instruksi Anda.
Odalrick
3
chances are the users will never write it down... and you will be told "Well it said something about a violation..." Inilah sebabnya mengapa Anda menggunakan alat pencatatan pengecualian untuk secara otomatis menghasilkan laporan kesalahan yang berisi jejak tumpukan dan bahkan mungkin mengirimnya ke server Anda. Saya punya satu pengguna satu kali yang tidak terlalu teknis. Setiap kali dia akan mengirim pesan dari kesalahan logger, itu akan menjadi sesuatu seperti "Saya tidak yakin apa yang saya lakukan salah, tapi ..." tidak peduli berapa kali saya menjelaskan bahwa kesalahan ini berarti bug ada di pihak saya . Tapi, saya selalu mendapat laporan kesalahan darinya!
Mason Wheeler
3

Sementara saya setuju bahwa pengecualian harus mengandung informasi sebanyak mungkin, atau setidaknya kurang generik. Dalam kasus tabel tidak ditemukan, nama tabel akan menyenangkan.

Tetapi Anda tahu lebih banyak tentang apa yang Anda coba lakukan di tempat dalam kode tempat Anda menerima pengecualian. Meskipun Anda sering benar-benar tidak dapat berbuat banyak untuk memperbaiki situasi ketika ada yang tidak beres di perpustakaan di luar kendali Anda, Anda dapat menambahkan informasi yang jauh lebih berguna tentang situasi di mana ada masalah.

Dalam kasus tabel tidak ditemukan, itu tidak akan banyak membantu Anda jika Anda diberitahu bahwa tabel yang tidak dapat ditemukan disebut SISWA, karena Anda tidak memiliki tabel seperti itu, dan string itu tidak ada dalam kode Anda.

Tetapi jika Anda menangkap pengecualian dan mengolahnya kembali dengan pernyataan SQL yang Anda coba jalankan, Anda akan lebih baik, karena ternyata Anda mencoba memasukkan catatan dengan bidang nama adalah Robert '); MAHASISWA TABEL DROP; (Selalu ada xkcd!)

Jadi, untuk memerangi perkecualian yang kurang informatif: cobalah menangkap kembali dengan lebih banyak informasi spesifik tentang apa yang Anda coba lakukan.

Saya mungkin harus menambahkan, agar ini lebih sebagai jawaban mengapa dalam pertanyaan itu, bahwa kemungkinan alasan mengapa fokus dari para pembuat perpustakaan belum membuat pesan pengecualian lebih baik, adalah bahwa mereka tidak tahu mengapa sesuatu telah dicoba gagal, logika itu ada dalam kode panggilan.

Bengkok
sumber
misal di C ++ Anda harus throw_with_nestedbanyak menggunakan .
Rute Mil
3

Untuk memberikan jawaban yang sedikit berbeda: Kode yang menyinggung mungkin telah dilakukan untuk menyatakan:

  • Fungsi menerima X dan mengembalikan Y
  • Jika X tidak valid, lempar pengecualian Z

Tambahkan tekanan untuk mengirim tepat ke spec (karena takut ditolak dalam peninjauan / pengujian) dalam waktu minimum dan dengan keributan minimum, maka Anda memiliki resep untuk pengecualian perpustakaan yang sepenuhnya sesuai dan tidak membantu.

Stu Pegg
sumber
3

Pengecualian memiliki biaya khusus bahasa dan implementasi.

Sebagai contoh, pengecualian C ++ diperlukan untuk menghancurkan semua data yang hidup antara melempar bingkai panggilan dan menangkap bingkai panggilan, dan itu mahal. Oleh karena itu, programmer tidak ingin banyak menggunakan pengecualian.

Di Ocaml, pengecualian melempar hampir secepat C setjmp(biayanya tidak tergantung pada jumlah frame panggilan yang dilalui), sehingga pengembang dapat menggunakannya banyak (bahkan untuk kasus yang tidak luar biasa, sangat umum,). Sebaliknya, pengecualian C ++ cukup berat sehingga Anda mungkin tidak akan sering menggunakannya seperti di Ocaml.

Contoh khas adalah beberapa pencarian atau eksplorasi rekursif yang dapat "dihentikan" di dalam rekursi yang cukup dalam (mis. Menemukan daun di pohon, atau fungsi penyatuan). Dalam beberapa bahasa lebih cepat (jadi lebih idiomatis) untuk menyebarkan kondisi itu ke setiap penelepon. Dalam bahasa lain, melempar pengecualian lebih cepat.

Jadi tergantung pada bahasa (dan kebiasaan pengembang menggunakannya), pengecualian dapat membawa banyak detail yang berguna, atau sebaliknya digunakan sebagai lompatan non-lokal cepat dan hanya membawa data yang sangat berguna.

Basile Starynkevitch
sumber
6
"Sebagai contoh, pengecualian C ++ diperlukan untuk menghancurkan semua data yang hidup antara melempar bingkai panggilan dan menangkap bingkai panggilan, dan itu mahal. Oleh karena itu, programmer tidak ingin banyak menggunakan pengecualian." Omong kosong total. Kekuatan utama pengecualian C ++ adalah destruktor disebut deterministik. Tidak ada yang akan menggunakannya jika mereka hanya melompat.
Rute Mil
Saya tahu itu, tetapi itu adalah fakta bahwa pengecualian C ++ tidak seperti Ocaml, dan Anda tidak menggunakannya seperti yang Anda lakukan di Ocaml.
Basile Starynkevitch
5
Anda tidak menggunakan pengecualian C ++ untuk aliran kontrol di C ++ terutama karena hal itu membuat kode tidak dapat dibaca dan sulit dimengerti.
Miles Rout
-2

Apa yang membuat Anda berpikir nilai indeks atau rentang yang diperlukan atau nama tabel adalah detail yang berguna, sebagai pengecualian?

Pengecualian bukanlah mekanisme penanganan kesalahan; mereka adalah mekanisme pemulihan .

Tujuan dari pengecualian adalah untuk menggembungkan ke tingkat kode yang dapat menangani pengecualian. Di mana pun level itu, baik Anda memiliki informasi yang dibutuhkan, atau itu tidak relevan. Jika ada informasi yang Anda butuhkan, tetapi tidak memiliki akses langsung ke, Anda tidak menangani pengecualian di tingkat yang sesuai.

Satu kali saya bisa memikirkan di mana informasi tambahan dapat membantu adalah pada tingkat atas absolut aplikasi Anda di mana Anda crash dan memancarkan dump kesalahan; tetapi itu bukan tugas pengecualian untuk mengakses, menyusun dan menyimpan informasi ini.

Saya tidak mengatakan bahwa Anda bisa meletakkan "lempar Pengecualian baru" di mana-mana dan menyebutnya baik, adalah mungkin untuk menulis pengecualian yang buruk. Tetapi termasuk informasi yang tidak relevan tidak perlu untuk menggunakannya dengan benar.

Odalrick
sumber
Saya tidak akan menggambarkan nama tabel database yang hilang sebagai tidak relevan walaupun saya mengerti, dan bersimpati dengan, poin yang Anda buat. Saya sudah memberikan Anda suara.
Daniel Hollinrake
1
@DanielHollinrake Ya, nama tabel jelas yang paling tidak relevan dari contoh. Dalam kode saya bekerja dengan, masalah semacam ini sangat umum dan melihat bagaimana nama tabel telah hancur memberikan petunjuk untuk apa yang salah. Saya sudah mencoba memikirkan contoh mengapa hal-hal ini tidak relevan dengan pengecualian; mungkin saya bisa menggunakan ini ...
Odalrick
Saya tidak setuju. Untuk menangani pengecualian, detail tambahan mungkin tidak diperlukan karena Anda hanya ingin melindungi aplikasi agar tidak macet tetapi akhirnya Anda harus memberi tahu mengapa itu tidak berfungsi dan dapat memperbaikinya. Jika Anda tidak memiliki petunjuk apa pun selain tipe pengecualian, maka sebaiknya lihat debugging.
t3chb0t
@ t3chb0t Itulah tumpukan jejak dan kelas pengecualian dan dump memori dan segala sesuatu yang lain untuk. Bagaimana ini akan membantu Anda jika seorang pelanggan menelepon dan mengatakan "Komputer memberi tahu saya bahwa ia mencoba mengakses indeks 5 dan tidak ada di sana.". Itu hanya bisa membantu jika Anda juga membuat serial daftar, dan konteks untuk daftar dan hal lain yang mungkin berguna. Anda seharusnya tidak membuat cerita bersambung seluruh kondisi aplikasi setiap kali Anda melemparkan pengecualian.
Odalrick
@Odalrick untuk pelanggan mungkin tidak memiliki arti apapun tetapi sebagai pengembang Saya menghargai setiap informasi yang saya bisa mendapatkan ;-) maka mungkin contoh lain: katakanlah SqlExeption terjadi dan itu semua yang kau tahu ... Hal ini jauh lebih mudah untuk memperbaiki itu jika Anda tahu koneksi string atau database atau tabel dll yang tidak berfungsi .... dan ini bahkan lebih penting jika aplikasi Anda menggunakan beberapa database. Jejak stack terperinci membutuhkan file-file pdb untuk dikirim dengan aplikasi ... itu tidak selalu mungkin. Juga dump memori dapat menjadi sangat besar dan tidak selalu dapat ditransfer.
t3chb0t