Mengapa saya harus menulis semua Pernyataan dalam Try-Catch?

12

Kepala perusahaan saya mengatakan bahwa saya harus menulis semua, yaitu SEMUA kode saya dalam pernyataan Coba-tangkap. Sekarang, saya dapat memahami pendekatan 'lebih baik aman daripada menyesal' di sini, tetapi bukankah terlalu hati untuk berpikir bahwa akan ada pengecualian ketika Label dibuat, posisi form ditetapkan. adakah contoh di mana Pengecualian dalam operasi sederhana tersebut.

CyprUS
sumber
4
Ini kedengarannya seperti istilah buzz oleh orang yang sama yang mengatakan bahwa semua SQL harus ditulis sebagai prosedur tersimpan untuk kinerja yang lebih baik.
Spong
5
Apakah Anda lebih suka, "Jika kode Anda membuat kesalahan run-time, Anda dipecat." Permainan ayam itu menyenangkan sampai Anda melihat lawan Anda melemparkan kemudi dan menginjak pedal rem ke luar jendela.
JeffO
4
@ Jeff O - Saya benar-benar percaya bahwa dalam pengembangan perangkat lunak lawan adalah kereta barang.
Joris Timmermans
5
Ungkapan terbaik yang pernah saya dengar untuk gaya penanganan perkecualian ini adalah "Memaku mayat dalam posisi tegak", artinya, meninggalkan aplikasi dalam keadaan tak terduga. Gagal Cepat, Gagal Keras adalah pendekatan yang jauh lebih modern, sehingga Anda benar-benar dapat mengatasi semua bug.
Brook
2
Subjek dari permintaan itu tidak relevan ... hanya mengatakan "kepala perusahaan saya mengatakan saya harus kode ..." adalah bendera merah besar. Ini manajemen mikro ... ini bukan pekerjaannya.
JoelFan

Jawaban:

14

Kepala perusahaan saya mengatakan bahwa saya harus menulis semua, yaitu SEMUA kode saya dalam pernyataan Coba-tangkap.

Nah, ini sedikit berlebihan dan hanya menyebabkan kode berisik. Apa manfaat memiliki semua kode (misalnya masing-masing metode) ditulis dengan try catch handler? Ini hanya memberitahu Anda ada kesalahan yang harus diperbaiki di sebagian besar kasus. Seringkali, pengecualian dapat dan harus dihindari sejak awal.

Pandangan pada jejak tumpukan sebagian besar cukup untuk mengungkapkan penyebab dalam kode Anda, bahkan jika metode patahan tidak melakukan tangkapan itu sendiri. Ada kalanya pengembang merusak tumpukan-jejak dalam pengecualian, tetapi itu jauh lebih sering terjadi ketika Anda memiliki banyak dan banyak penangan pengecualian. Seperti apa pun: Sedikit itu baik, tetapi terlalu banyak racun.

Penanganan pengecualian memang cukup sederhana:

Tangkap Pengecualian

  • kapan pun Anda membutuhkan tindakan khusus sebagai reaksi terhadap pengecualian
  • setiap kali pengecualian akan meninggalkan program dalam keadaan tidak konsisten jika tidak ditangani

Jika Anda memikirkannya, maka selalu ada hanya satu tempat yang bagus untuk menangani pengecualian yang terjadi. Dan dengan demikian pawang harus berada di tempat itu.

Banyak pengecualian bahkan tidak boleh dilemparkan sejak awal, jadi jangan membangun struktur kontrol Anda di sekitar penanganan pengecualian, daripada mencoba untuk menghindari kemungkinan terjadinya pengecualian kapanpun dan dimanapun memungkinkan.

Ingatlah untuk menabrak lebih awal ketika segala sesuatu berjalan (tidak dapat diperbaiki) salah. Memasukkan semua kode dalam pernyataan coba-coba adalah tidak masuk akal, tetapi jangan lupa untuk melaporkan dan mencatat SEMUA pengecualian.

Elang
sumber
+1 Tidak hanya mengarahkan ini ke kode yang bising, tetapi kinerja yang lebih buruk. Saat Anda meletakkan pernyataan di blok percobaan, Penyusun HotSpot tidak akan dapat menerapkan optimisasi yang sebaliknya akan ia lakukan.
Oliver Weiler
@Oliver Weiler: Apakah Anda memiliki kutipan yang menjelaskan optimasi apa yang tidak dilakukan oleh kompiler HotSpot di blok coba / tangkap?
Kaypro II
16

tetapi bukankah terlalu hati untuk berpikir bahwa akan ada pengecualian ketika Label dibuat, posisi form ditetapkan. adakah contoh di mana Pengecualian dalam operasi sederhana tersebut.

Pastinya ya! Selalu ada cara untuk melakukan kesalahan yang tidak Anda perkirakan. Dan "hati ayam" adalah ungkapan konyol untuk digunakan dalam konteks ini; pengembangan perangkat lunak bukan tentang membuktikan kejantanan Anda dengan mengabaikan masalah potensial.

Apa adalah pertanyaan yang valid adalah apakah itu berguna untuk pengecualian untuk ditangkap pada titik di mana standar coding Anda mengatakan mereka harus. Pernyataan Anda berbunyi seperti Anda harus mencoba / menangkap blok di setiap badan metode, dan itu memang tidak masuk akal karena Anda sering tidak dapat langsung melakukan sesuatu yang berguna dengan pengecualian, dan itu sebenarnya inti dari semua perkecualian: bahwa Anda dapat memilih untuk membiarkannya menyebarkan tumpukan panggilan untuk ditangani pada titik yang sesuai.

Michael Borgwardt
sumber
13
Aplikasi saya lebih tahu daripada membuang pengecualian atau mereka akan mendapatkan pukulan seumur hidup. Begitu mereka mengira Anda berhati ayam, mereka akan menabrak Anda.
JeffO
@Michael Borgwardt: hehe, jadi Anda menurunkan saya. Anda downvoted pada pertanyaan ini dan satu-satunya downvote ada di posting saya. Anda tampaknya memiliki masalah serius dengan ego atau harga diri Anda. Saya memperhatikan hal itu pada pertanyaan-pertanyaan lain juga. Anda tahu, programmer lain juga punya jawaban yang bagus.
Falcon
@ Falcon: Saya tidak melakukan downvote pada pertanyaan ini. Saya tidak tahu apa yang membuat Anda percaya sebaliknya, tetapi jika seseorang memiliki masalah ego yang serius, itu adalah Anda.
Michael Borgwardt
@Michael Borwardt: Mungkin saya salah. Dalam hal ini saya minta maaf. Bisa jadi itu hanya downvote pada pertanyaan Anda sendiri yang membuat saya berpikir bahwa Anda turun di sini. Maaf.
Falcon
8

Saya akan membalikkan ini sebaliknya. Ya, sebagai aturan umum, penanganan pengecualian adalah hal yang baik, tetapi bisakah Anda benar-benar menangani setiap kemungkinan pengecualian dengan cara yang masuk akal pada titik di mana ia ditangkap? Kadang-kadang, terutama jika Anda tidak menulis perangkat lunak mission-critical, itu adalah lebih baik untuk hanya jatuh dan terbakar dalam beberapa cara setengah jalan-dikendalikan bila ada sesuatu yang tidak beres.

Jika Anda tidak dapat 100% yakin bahwa Anda dapat menangani setiap pengecualian tunggal yang mungkin ditangkap, Anda mungkin lebih baik menulis semacam pengendali pengecualian umum, membungkus loop utama program di dalamnya - mekanisme yang tepat bagaimana melakukannya dengan jelas tergantung pada bahasa tempat Anda bekerja. Di sana, catat sebanyak mungkin detail tentang pengecualian, simpan status program (di tempat lain selain dari penyimpanan data apa pun yang saat ini digunakan pengguna - ingat, semuanya mungkin rusak pada saat ini ), dan seterusnya. Kemudian, rethrow eksepsi dan biarkan OS menanganinya namun itu cocok. Dalam penangan pengecualian menangkap semua ini, bersiaplah untuk kegagalan katastropik. Kemudian, ketika program dimulai kembali, lihat apakah kondisi ini bermanfaat, dan pulihkan apa yang bisa diselamatkan jika itu; dan mungkin menawarkan pengguna untuk mengirim laporan bug kembali kepada Anda.

sebuah CVn
sumber
5
+1: Jangan pernah menangkap pengecualian jika Anda tidak bisa segera menanganinya dengan benar. (Sayangnya, kadang-kadang Anda harus menjebaknya hanya untuk membiarkannya berkeliaran lagi tetapi ditandai sebagai jenis yang berbeda, sebagai bagian dari pemaksaan API: Saya benci itu.)
Donal Fellows
6

Secara keseluruhan, menggunakan try / catch yang banyak sudah usang, karena catch block sangat mahal dari sudut sumber daya. Coba / tangkap penggunaan mengingatkan saya pada manajemen risiko . Manajemen risiko memiliki dua dimensi:

  1. Peluang terjadinya risiko
  2. Kerusakan yang dimilikinya

Sekarang, jika Anda keluar dari rumah Anda, piano jatuh di kepala Anda di suatu tempat sementara sangat tidak mungkin terjadi (mungkin 0,001%), tetapi dapat membunuh Anda.

Penanganan pengecualian seperti itu. Coba blok tidak mahal. Tetapi catch block sangat mahal, karena perlu membuat tabel stack stack, dan melakukan hal-hal lain. Karena itu dalam membuat keputusan tentang coba / tangkap balok, Anda harus mempertimbangkan berapa kali Anda mungkin mengenai tangkap balok. Jika di antara 10.000 penggunaan, Anda hanya menekannya 1 kali, lalu gunakan. Tetapi jika itu adalah formulir, dan pengguna mungkin tidak mengisinya dengan benar 50% kali, maka Anda harus menghindari menempatkan blok coba / tangkap ke dalam tindakan di sana.

Di tempat-tempat di mana probabilitas terjadinya pengecualian tinggi, disarankan untuk menggunakan if {} else {}blok untuk menghindari terjadinya pengecualian. Misalnya, tempat Anda ingin membagi dua angka, alih-alih menulis:

try
{
    int result = a/b;
}
catch (DivisionByZeroException ex)
{
    // Showing a message here, and logging of course.
}

Anda harus menulis:

if (b == 0)
{
    int result = a/b;
}
else
{
    // Showing a message to user to change the value of b, etc.
}
Saeed Neamati
sumber
2
+1 untuk menggunakan if / else untuk menangani "pengecualian" yang pada dasarnya hanya logika aplikasi.
Morgan Herlocker
Jika itu terkait pengguna, ingatlah bahwa komputer jauh lebih cepat daripada orang. Pengecualian yang diberikan pada 50% dari pengiriman formulir masih mungkin terjadi beberapa kali per detik bahkan dengan banyak pengguna.
Donal Fellows
1
Saya tidak setuju dengan Anda untuk menghindari blok coba / tangkap. Terus-menerus mencoba mengantisipasi pengecualian adalah kesalahan, mahal dalam waktu pengembang, dan membuat kode Anda lebih sulit dibaca. Sebuah loop yang melempar sejuta pengecualian dan menangkapnya membutuhkan 500ms untuk berjalan di mesin saya (vs 1ms untuk loop kosong), yang bukan perbedaan kinerja dunia nyata dalam 99,99% kasus (dan semua kode UI). Anda harus menggunakan pengecualian kecuali dalam kasus-kasus di mana Anda mengetahui masalah penalti kinerja, karena mereka membuat kode Anda lebih dapat diandalkan dan membiarkan Anda menganggap bahwa kode sebelumnya dieksekusi dengan sukses.
Kaypro II
@ cosmic.osmo, apakah Anda mengambil stacktrace atau hanya menangkapnya?
3

Anda harus menggunakan try-catch saat yang tepat, tapi tolong oh tolong jangan menangkap semua pengecualian dan bahkan tidak mencatatnya. Pada saat itu kode bau dan pekerjaan buruk.

ist_lion
sumber
1
+1 untuk logging. Program di alam bebas adalah kotak hitam. Ketika mereka gagal, sebuah log yang mengatakan "Inilah yang terjadi" berjalan sangat jauh untuk menyelesaikan masalah. Saya memiliki kesalahan dalam program saya yang tidak dilaporkan, dan mereka terungkap hanya setelah saya menemukannya di log.
Andrew Neely
2

Saya pribadi tidak tahan dengan pengecualian, mereka SANGAT, SANGAT, SANGAT sulit ditangani dengan benar. Dan berusaha untuk merusak data yang korup itu SANGAT, SANGAT, SANGAT sulit!

http://blogs.msdn.com/b/mgrier/archive/2004/02/18/75324.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

http://www.joelonsoftware.com/items/2003/10/13.html

Jika Anda tidak memanggil setiap fungsi seperti:

try
{
    TrivialFunction();
}
catch(TypeAException)
{
    //MaybeFix
}
catch(TypeBException)
{
    //MaybeFix
}
catch(TypeCException)
{
    //NO FIX - CORRUPT DATA
}
catch(TypeDException)
{
    //NO FIX - UNKNOWN STATE
}
catch(OutOfMemoryException)
{
    //Try to fix this one! Destructors might allocate on their own ;)
}
catch(Exception)
{
    //Nothing to see here, move on, everything is OK ;)
}

Tidak ada cara Anda akan membersihkan dengan benar di setiap titik keluar. Pengecualian adalah KERAS!

Satu-satunya hal yang baik tentang pengecualian adalah bahwa jika Anda tidak menangkapnya, aplikasi mogok karena perilaku yang tidak terduga.

Coder
sumber