Apakah kesalahan menekan praktik buruk?


14

Pada pertanyaan SO, saya bertanya di sini tentang beberapa kode yang saya tidak yakin, seseorang menjawab "BTW, kode mengerikan di sana: ia menggunakan simbol penekan kesalahan (@) banyak."

Apakah ada alasan mengapa ini merupakan praktik yang buruk? Dengan hal-hal seperti:

$db=@new mysqli($db_info) or die('Database error');

, itu memungkinkan saya untuk menampilkan hanya pesan kesalahan khusus. Tanpa penindasan kesalahan, maka masih akan menampilkan pesan PHP khas:

Peringatan : mysqli :: mysqli (): php_network_getaddresses: getaddrinfo gagal: Tidak ada host yang dikenal. di beberapa \ file \ path pada baris 6

serta 'Kesalahan basis data'.

Apakah penindasan kesalahan selalu buruk, dan jika demikian, apa yang khususnya tentang hal di atas yang buruk?

Perbarui: kode aktual yang saya gunakan adalah:

or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b><br />Error occurred on line <b>' . __LINE__ . '</b> of <b>' . __FILE__ . '</b>' : ''))

yang menghapus semua output sebelumnya dan menampilkan pesan kesalahan. Jadi fakta bahwa pesan kesalahan tidak termasuk rincian tentang apa yang terjadi secara spesifik (yang orang tampaknya sarankan sebagai alasan mengapa penindasan kesalahan buruk) tidak relevan.


9
Apakah mengenakan penutup mata saat Anda mengemudi praktik yang buruk?
Damien Roche

Bagaimana ini bisa menjadi pertanyaan serius? Saya kira jika Anda suka menulis kode yang membutuhkan waktu berjam-jam untuk debug, penindasan kesalahan akan menjadi hal yang baik. Pikirkan tentang hal itu, aplikasi Anda gagal, merusak data ... dan Anda tidak ingin tahu mengapa atau di mana dalam kode. Kapan itu akan menjadi ide yang bagus? Anda harus mengundang teman Anda untuk melakukan pesta selimut pada Anda ... itu mengikuti logika yang sama.
Some Free Mason

1
@ SomeFreeMason Jika saya perlu men-debug maka saya hanya akan menetapkan $ debug_mode ke TRUE, karena kode aktual yang saya gunakan adalah:or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b>' : ''))

@Paradoxical: Saya menyadari keadaan pengecualian / penanganan kesalahan di PHP agak FUBAR, tetapi Anda sadar bahwa Anda dapat mematikan tampilan visual kesalahan dalam konfigurasi PHP Anda, bukan?
Phoshi

@Phoshi sayangnya layanan hosting yang saya gunakan tidak memberi saya akses ke php.ini

Jawaban:


14

Saya pikir Anda melakukan hal yang benar dengan menekan kesalahan, karena Anda menerapkan penanganan kesalahan Anda sendiri.

Mungkin lebih mudah untuk mempertimbangkan padanan dalam, katakanlah, Java. Menekan kesalahan menggunakan @analog dengan menelan pengecualian. Kode berikut, yang mirip dengan Anda, masuk akal:

try {
    db = new MySQLi(dbInfo);
} catch (SQLException connectionFailure) {
    die("Database error");
}

(Ya, di Jawa, Anda tidak ingin mesin servlet mati, tetapi Anda mendapatkan idenya.)

Namun, ini tidak dapat diterima:

try {
    db = new MySQLi(dbInfo);
} catch (Exception e) {
}

Kebanyakan penindasan kesalahan PHP dilakukan secara sembarangan, analog dengan contoh terakhir, karenanya reaksi spontan terhadap kode Anda.


3
Saya tidak akan memanggil menangkap pengecualian dan hanya menghentikan eksekusi untuk "menangani" itu. Jika Anda dapat memecahkan masalah, bagus, lakukanlah. Jika Anda tidak bisa, apa yang Anda lakukan untuk menangkapnya? Untuk inilah kami memiliki penangan pengecualian tingkat atas. Menangkap pengecualian dalam hal ini hanya memastikan Anda memiliki kode penanganan kesalahan yang tersebar di seluruh basis kode Anda.
Phoshi

7

Penindasan kesalahan buruk, karena tidak hanya menyembunyikan informasi yang sudah Anda ketahui ( ada yang salah). Mungkin juga menyembunyikan informasi penting untuk debugging yang tidak Anda sadari ( apa , di mana dan mengapa ).

Dalam contoh khusus ini, " Kesalahan basis data " bukan pesan kesalahan yang sangat baik. Ada yang salah dengan DB. Tidak terlalu mencerahkan. " Peringatan: mysqli :: mysqli (): php_network_getaddresses: getaddrinfo gagal: Tidak ada host yang dikenal. di beberapa \ file \ path on line 6 "sebenarnya adalah pesan kesalahan yang lebih baik. Ini memberi Anda lokasi dan alasan untuk masalah tersebut. Anda dapat langsung masuk dan mulai men-debug, karena kesalahan sudah ditemukan.

Tentu saja, perancang perpustakaan terkadang memiliki kecenderungan untuk memunculkan banyak peringatan yang tidak relevan. Saya tidak tahu PHP cukup baik untuk mengetahui apakah ia memiliki cara untuk menyaring peringatan yang Anda tidak tertarik. Saya tahu bahwa membaca stacktrace seratus baris tidak terlalu mencerahkan. Tetapi respons yang benar terhadap terlalu banyak informasi bukanlah untuk mengurangi jumlah informasi menjadi nol , tetapi untuk menyaring bagian yang tidak relevan pada tahap tertentu. The @operator tidak memiliki rincian ini (moto itu adalah semua atau tidak ), dan karena itu bukan merupakan alat yang cocok untuk manajemen kesalahan yang efektif.

Ada beberapa kasus di mana Anda tahu bahwa kesalahan tertentu akan muncul, dan bahwa memperbaiki masalah sebenarnya lebih mahal daripada membungkam pesan (dan berpotensi mengalami kejatuhan karena itu). Ini bisa menjadi kasus dalam skrip satu kali, tetapi menempelkan jari Anda ke telinga Anda dan pergi " la la la " bukan respons profesional terhadap bug (potensial).


5
Anda tidak ingin memberi tahu pengguna kesalahan yang sebenarnya. Anda memberi tahu mereka bahwa kesalahan ada di pihak Anda dan bahwa Anda sedang mengusahakannya. Anda bisa mencatat kesalahan pada server Anda dan mengatur peringatan agar Anda akan mengetahuinya secara otomatis, tetapi tidak ada alasan untuk menunjukkan kesalahan ini kepada pengguna.
Jeroen Vannevel

1
Di situs langsung, pasti akan lebih baik untuk pesan kesalahan yang dapat dipahami oleh pengguna biasa untuk ditampilkan, daripada "beberapa sampah teknis tentang mysqli, apa pun itu", meskipun? Jika saya mencoba untuk debug itu maka saya akan menghapus penekanan kesalahan, tetapi di situs langsung, saya tidak setuju bahwa kesalahan penuh harus ditampilkan.

3
@ Paradoksikal Di situs yang serius, Anda tidak akan menampilkan pesan kesalahan seperti "kesalahan basis data" dan tidak ada yang lain. Anda akan menampilkan halaman "internal server error" umum dengan banyak bulu ekstra, gaya, footer, dll. Yang dietidak cocok untuk keduanya. Dan informasi terperinci harus masuk ke log terlepas dari apa yang Anda tunjukkan kepada pengguna .

1
Apakah tidak ada cara untuk menyajikan pesan yang ramah pengguna di layar dan menulis pesan teknis ke file log?
FrustratedWithFormsDesigner

3
display_errorsoff, log_errorson, dan Anda cukup baik untuk pergi, lakukan sesuka Anda pada mendeteksi kesalahan, tetapi jangan membuangnya.
Wrikken

0

Kesalahan penekan buruk karena menyembunyikan masalah, yang sering kali tidak kita sadari dan dapat mengakibatkan perilaku tak terduga yang mungkin terbukti sangat mahal dalam beberapa aplikasi penting misalnya dalam aplikasi yang digunakan dalam bidang keuangan, kesehatan, dan pertahanan.

Ini juga bukan ide yang baik untuk memiliki pengecualian yang tidak tertangani dalam kode dan menunjukkan pesan kesalahan yang sebenarnya kepada pengguna karena dapat mengakibatkan masalah keamanan karena pesan kesalahan biasanya mengungkapkan banyak tentang kode Anda, yang dapat membantu pengguna jahat dan peretas untuk memanipulasi sistem.

Jadi praktik yang baik adalah menangani kesalahan pada tingkat yang berbeda, misalnya pada tingkat tertinggi Anda dapat menangani kesalahan hanya dengan masuk kesalahan aktual dan menampilkan pesan yang sederhana dan ramah pengguna kepada pengguna.


0

Ya, operator penekan kesalahan umumnya adalah ide yang buruk.

Anda harus mengelola pelaporan kesalahan dalam konfigurasi ( php.ini). Jadi, Anda dapat memilih pengaturan yang berbeda untuk setiap lingkungan (misalnya, cuti peringatan dalam pengembangan dan menyembunyikannya dalam produksi).

Satu-satunya situasi ketika menggunakan @bisa masuk akal adalah ketika Anda mengembangkan perpustakaan untuk pengembang lain. Jika Anda secara sukarela memilih untuk melakukan sesuatu yang menghasilkan peringatan, dan tidak ingin mengganggu pengguna perpustakaan Anda dengan peringatan yang tidak bergantung pada mereka, @bisa menjadi solusi.

Saya tidak bisa memikirkan penggunaan lainnya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.