Argumen untuk atau menentang menggunakan Try / Catch sebagai operator logis [ditutup]

36

Saya baru saja menemukan beberapa kode indah di aplikasi perusahaan kami yang menggunakan blok Try-Catch sebagai operator logis.
Berarti, "lakukan beberapa kode, jika itu melempar kesalahan ini, lakukan kode ini, tetapi jika itu melempar kesalahan ini lakukan hal ke-3 ini sebagai gantinya".
Ini menggunakan "Akhirnya" sebagai pernyataan "lain" yang muncul.
Saya tahu bahwa ini salah secara inheren, tetapi sebelum saya pergi bertengkar saya berharap untuk beberapa argumen yang dipikirkan dengan matang.
Dan hei, jika Anda memiliki argumen untuk penggunaan Try-Catch dengan cara ini, mohon beri tahu.

Bagi siapa pun yang bertanya-tanya, bahasanya adalah C # dan kode yang dimaksud adalah sekitar 30+ baris dan sedang mencari pengecualian spesifik, itu tidak menangani SEMUA pengecualian.

James P. Wright
sumber
13
Saya hanya punya argumen yang menentang praktik ini, dan karena Anda tampaknya sudah yakin itu adalah ide yang buruk, saya tidak akan repot mempostingnya.
FrustratedWithFormsDesigner
15
@FrustratedWIthFormsDesigner: Itu alasan yang buruk. Bagaimana dengan orang-orang yang tidak yakin? Bagaimana dengan pertanyaan saya yang sebenarnya di mana saya secara khusus menanyakan alasannya karena saya tidak dapat benar-benar mengatakan "mengapa" hanya saja saya tahu itu salah.
James P. Wright
3
Pendapat saya sangat tergantung pada apa kode yang dimaksud sebenarnya. Ada hal-hal yang tidak dapat diperiksa sebelumnya (atau memungkinkan kondisi ras ketika mencoba, seperti banyak operasi file - dalam penundaan antara pemeriksaan dan operasi, apa pun dapat terjadi pada file) dan harus dilakukan try. Tidak setiap kasus pengecualian yang menuntut pengecualian pada umumnya harus berakibat fatal dalam kasus khusus ini. Jadi, dapatkah Anda melakukannya dengan cara yang lebih sederhana, sama atau lebih kuat tanpa menggunakan pengecualian?
11
Saya harap mereka tidak benar-benar menggunakan blok "akhirnya" sebagai "lain" karena blok "akhirnya" selalu dijalankan setelah kode sebelumnya terlepas dari segala pengecualian yang dilemparkan.
jimreed
2
Bahasa apa yang mereka gunakan? Tidak apa-apa, katakanlah, OCaml, di mana perpustakaan standar melempar pengecualian secara rutin. Penanganan pengecualian sangat murah di sana. Tetapi tidak akan seefisien itu di CLI atau JVM.
SK-logic

Jawaban:

50

Penanganan pengecualian cenderung menjadi cara yang mahal untuk menangani kontrol aliran (tentu untuk C # dan Java).

Runtime bekerja cukup banyak ketika objek pengecualian dikonstruksi - mendapatkan jejak stack bersama-sama, mencari tahu di mana pengecualian ditangani dan banyak lagi.

Semua ini menghabiskan sumber daya memori dan CPU yang tidak perlu diperluas jika pernyataan kontrol aliran digunakan untuk kontrol aliran.

Selain itu, ada masalah semantik. Pengecualian untuk situasi luar biasa, bukan untuk kontrol aliran normal. Seseorang harus menggunakan penanganan pengecualian untuk menangani situasi yang tidak terduga / luar biasa, tidak seperti aliran program normal, karena jika tidak, pengecualian yang tidak tertangkap akan memberi tahu Anda jauh lebih sedikit.

Terlepas dari dua ini, ada masalah orang lain membaca kode. Menggunakan pengecualian dengan cara seperti itu bukanlah sesuatu yang sebagian besar programmer akan harapkan, jadi keterbacaan dan bagaimana dimengerti kode Anda menderita. Ketika seseorang melihat "Pengecualian", orang berpikir - sesuatu yang buruk terjadi, sesuatu yang tidak seharusnya terjadi secara normal. Jadi, menggunakan pengecualian dengan cara ini benar-benar membingungkan.

Oded
sumber
1
Poin yang bagus tentang kinerja, meskipun ini juga akan tergantung pada spesifikasi platform.
FrustratedWithFormsDesigner
4
Jika itu satu-satunya kelemahan, terima kasih - saya akan menyerahkan kinerja setiap hari jika itu membeli saya kode yang lebih baik (kecuali di jalur kinerja-kritis, yaitu; tapi untungnya itu hanya 20% dari semua kode bahkan dalam aplikasi yang umumnya kinerja -kritis).
5
@delnan - Tidak, bukan satu-satunya downside.
Oded
2
Selain kata unaticipated, saya setuju dengan posting Anda. Ada waktu dalam kode Anda di mana pengecualian terjadi. Kebanyakan dari mereka harus dapat diprediksi seperti kegagalan koneksi dengan DB atau panggilan layanan atau kapan saja Anda berurusan dengan kode yang tidak dikelola. Anda menangkap masalah di luar kendali Anda dan menanganinya. Tapi saya setuju Anda tidak boleh memiliki kontrol aliran berdasarkan pengecualian yang dapat Anda hindari dalam kode Anda.
SoylentGray
4
"Penanganan pengecualian cenderung menjadi cara yang mahal untuk menangani kontrol aliran". Salah untuk Python.
S.Lott
17

Saya baru saja menemukan beberapa kode indah di aplikasi perusahaan kami yang menggunakan blok Try-Catch sebagai operator logis. Berarti, "lakukan beberapa kode, jika itu melempar kesalahan ini, lakukan kode ini, tetapi jika itu melempar kesalahan ini lakukan hal ke-3 ini sebagai gantinya". Ini menggunakan "Akhirnya" sebagai pernyataan "lain" yang muncul. Saya tahu bahwa ini salah secara inheren ...

Bagaimana Anda tahu bahwa? Saya menyerahkan semua "pengetahuan" semacam itu dan sekarang hanya percaya bahwa kode yang paling sederhana adalah yang terbaik. Misalkan Anda ingin mengonversi string ke Opsional yang kosong jika parse gagal. Tidak ada yang salah dengan:

try { 
    return Optional.of(Long.valueOf(s)); 
} catch (NumberFormatException) { 
    return Optional.empty(); 
}

Saya sepenuhnya tidak setuju dengan interpretasi biasa "Pengecualian untuk kondisi luar biasa". Ketika suatu fungsi tidak dapat mengembalikan nilai yang dapat digunakan atau metode tidak dapat memenuhi kondisi pasca-nya, berikan pengecualian. Tidak masalah seberapa sering pengecualian ini dilemparkan sampai ada masalah kinerja yang ditunjukkan.

Pengecualian menyederhanakan kode, dengan memungkinkan pemisahan penanganan kesalahan dari aliran normal. Cukup tulis kode yang paling sederhana, dan jika lebih mudah menggunakan try-catch atau melempar pengecualian, maka lakukan itu.

Pengecualian menyederhanakan pengujian dengan mengurangi jumlah jalur melalui kode. Fungsi tanpa cabang akan melengkapi atau melempar pengecualian. Fungsi dengan banyak ifpernyataan untuk memeriksa kode kesalahan memiliki banyak jalur yang memungkinkan. Sangat mudah untuk mendapatkan salah satu kondisi yang salah, atau melupakan sepenuhnya, sehingga beberapa kondisi kesalahan diabaikan.

kevin cline
sumber
4
Saya pikir ini sebenarnya argumen yang cukup bagus. Kode Anda bersih dan ringkas dan masuk akal dalam apa yang dilakukannya. Ini sebenarnya mirip dengan apa yang terjadi dalam kode yang saya lihat, hanya saja jauh lebih kompleks, bersarang dan menjangkau lebih dari 30 baris kode.
James P. Wright
@ James: terdengar seperti kode akan baik-baik saja jika Anda mengekstrak beberapa metode yang lebih kecil.
kevin cline
1
Orang bisa berpendapat bahwa Java benar-benar bisa menggunakan sesuatu yang lebih seperti TryParse C #. Dalam C # kode itu akan menjadi int i; if(long.TryParse(s, out i)) return i; else return null;. TryParse mengembalikan false jika string tidak dapat diuraikan. Jika itu dapat diuraikan itu menetapkan argumen output ke hasil penguraian dan mengembalikan true. Tidak ada pengecualian terjadi, (bahkan secara internal di TryParse) dan terutama tidak ada pengecualian dari jenis yang berarti kesalahan programmer, seperti .NETs FormatExceptionselalu menunjukkan.
Kevin Cathcart
1
@ Kevin Cathcart, tapi mengapa itu lebih baik? kode yang menangkap NumberFormatException jauh lebih jelas bagi saya kemudian memeriksa hasil TryParse untuk nol.
Winston Ewert
1
@ ChrisMiskowiec, saya curiga mana yang Anda temukan lebih jelas adalah soal apa yang biasa Anda lakukan. Saya menemukan menangkap pengecualian lebih mudah diikuti kemudian memeriksa nilai-nilai ajaib. Tapi itu semua subjektif. Secara obyektif, saya pikir kita harus memilih pengecualian karena mereka memiliki default waras (crash program), daripada default yang menyembunyikan bug (lanjutkan seolah-olah tidak ada yang terjadi). Memang benar bahwa .NET berkinerja buruk dengan pengecualian. Tapi itu hasil dari desain .NET, bukan sifat pengecualian. Jika di .NET, ya Anda harus melakukannya. Namun pada prinsipnya, pengecualian lebih baik.
Winston Ewert
12

Pekerjaan debug dan pemeliharaan sangat sulit ketika aliran kontrol dilakukan dengan menggunakan pengecualian.

Secara inheren, pengecualian dirancang untuk menjadi mekanisme untuk mengubah aliran kontrol normal program Anda - melakukan aktivitas yang tidak biasa, menyebabkan efek samping yang tidak biasa, sebagai cara untuk keluar dari ikatan yang sangat ketat yang tidak dapat ditangani dengan lebih mudah. cara. Pengecualian luar biasa. Ini berarti bahwa, tergantung pada lingkungan mana Anda bekerja, penggunaan pengecualian untuk aliran kontrol reguler dapat menyebabkan:

  • Inefisiensi Lingkaran tambahan yang harus dilompati oleh lingkungan untuk melakukan perubahan konteks yang relatif sulit secara aman yang diperlukan untuk pengecualian memerlukan instrumentasi dan sumber daya.

  • Kesulitan debug Kadang-kadang informasi yang berguna (ketika mencoba men-debug suatu program) dikeluarkan dari jendela ketika pengecualian terjadi. Anda bisa kehilangan jejak status program atau riwayat yang relevan untuk memahami perilaku run-time

  • Masalah perawatan Alur eksekusi sulit ditindaklanjuti melalui lompatan pengecualian. Di luar itu, pengecualian dapat dilempar dari dalam kode jenis kotak hitam, yang mungkin tidak berperilaku mudah dimengerti saat melempar pengecualian.

  • Keputusan desain yang buruk Program yang dibangun dengan cara ini mendorong kerangka berpikir yang, dalam banyak kasus, tidak mudah dipetakan untuk menyelesaikan masalah secara elegan. Kompleksitas program akhir membuat programmer tidak memahami sepenuhnya pelaksanaannya, dan mendorong pengambilan keputusan yang mengarah pada perbaikan jangka pendek dengan biaya jangka panjang yang tinggi.

blueberryfields
sumber
10

Saya telah melihat pola ini digunakan beberapa kali.

Ada 2 masalah utama:

  • Ini sangat mahal (instantiasi objek pengecualian, mengumpulkan tumpukan panggilan, dll.). Beberapa kompiler mungkin benar-benar dapat mengoptimalkannya, tetapi saya tidak akan mengandalkan itu dalam kasus ini, karena pengecualian tidak dimaksudkan untuk penggunaan seperti itu, karena itu Anda tidak dapat mengharapkan orang untuk mengoptimalkannya.
  • Menggunakan pengecualian untuk aliran kontrol sebenarnya adalah lompatan, mirip seperti a goto. Lompatan dianggap berbahaya, karena sejumlah alasan. Mereka harus digunakan, jika semua alternatif memiliki banyak kerugian. Bahkan, dalam semua kode saya, saya hanya ingat 2 kasus, di mana lompatan jelas merupakan solusi terbaik.
back2dos
sumber
2
Hanya menaruhnya di sana, jika / juga dianggap lompatan. Perbedaannya adalah bahwa ini adalah lompatan yang hanya dapat terjadi di tempat tertentu (dan itu jauh lebih mudah dibaca) dan Anda tidak perlu khawatir tentang nama-nama label (yang Anda tidak harus dengan coba / tangkap juga , tetapi membandingkan dengan goto). Tapi hanya mengatakan "itu lompatan, yang buruk" juga mengatakan bahwa / jika itu buruk, padahal tidak.
jsternberg
1
@ jsternbarg: Ya, jika / yang lain sebenarnya dikompilasi untuk melompat pada level mesin, tetapi pada level bahasa, target lompat adalah pernyataan berikutnya, sedangkan dalam kasus loop, itu adalah pernyataan saat ini. Saya berpendapat, bahwa itu lebih merupakan langkah, daripada lompatan;)
back2dos
9

Terkadang pengecualian paling cepat. Saya telah melihat kasus di mana pengecualian objek nol lebih cepat bahkan di Jawa daripada menggunakan struktur kontrol (saya tidak bisa mengutip studi saat ini, jadi Anda harus percaya padaku). Masalahnya muncul ketika Java harus benar-benar meluangkan waktu dan mengisi jejak stack kelas pengecualian kustom alih-alih menggunakan yang asli (yang tampaknya setidaknya sebagian di-cache). Sebelum mengatakan bahwa ada sesuatu yang secara sepihak lebih cepat atau lebih lambat, ada baiknya untuk membandingkan.

Dalam Python tidak hanya lebih cepat, tetapi jauh lebih benar untuk melakukan sesuatu yang dapat menyebabkan pengecualian dan kemudian menangani kesalahan. Ya, Anda dapat menerapkan sistem tipe, tetapi itu bertentangan dengan filosofi bahasa - alih-alih Anda hanya perlu mencoba memanggil metode dan menangkap hasilnya! (Menguji apakah suatu file dapat ditulisi mirip - coba tuliskan dan tangkap kesalahannya).

Saya telah melihat saat-saat lebih cepat melakukan sesuatu yang bodoh seperti tabel kueri yang tidak ada di sana daripada mencari tahu apakah sebuah tabel ada di PHP + MySQL ( pertanyaan di mana saya membuat tolok ukur ini adalah satu-satunya jawaban yang diterima dengan suara negatif) .

Semua itu mengatakan, penggunaan pengecualian harus dibatasi karena beberapa alasan:

  1. Menelan pengecualian bersarang secara tidak disengaja. Ini penting. Jika Anda menangkap beberapa pengecualian bersarang yang berusaha ditangani oleh orang lain, Anda baru saja menembak rekan programmer Anda (mungkin bahkan Anda!) Di kaki.
  2. Tes menjadi tidak jelas. Blok kode yang memiliki pengecualian di dalamnya dapat memiliki salah satu dari beberapa hal yang salah dengannya. Boolean, di sisi lain, sementara secara teori itu bisa menjengkelkan untuk debug, pada umumnya tidak. Ini terutama benar karena para try...catchpenganut aliran kontrol umumnya (menurut pengalaman saya) tidak mengikuti filosofi "meminimalkan kode dalam blok coba".
  3. Itu tidak memungkinkan untuk else ifblok. Cukup berkata (dan jika seseorang membalas dengan "Tapi mereka bisa menggunakan kelas pengecualian yang berbeda", respons saya adalah "Pergi ke kamar Anda dan jangan keluar sampai Anda memikirkan apa yang Anda katakan.")
  4. Ini secara tata bahasa menyesatkan. Exception, ke seluruh dunia (seperti tidak menganut try...catchfilosofi aliran kontrol), berarti sesuatu telah memasuki keadaan yang tidak stabil (meskipun mungkin dapat dipulihkan). Keadaan yang tidak stabil adalah BURUK dan itu harus membuat kita semua terjaga di malam hari jika kita benar-benar memiliki pengecualian yang dapat dihindari (itu benar-benar membuatku takut, tidak bohong).
  5. Itu tidak sesuai dengan gaya pengkodean umum. Pekerjaan kita, baik dengan kode kita maupun dengan UI kita adalah membuat dunia sejelas mungkin. try...catchcontrol-flow bertentangan dengan apa yang umumnya dianggap praktik terbaik. Ini berarti dibutuhkan lebih banyak waktu bagi seseorang yang baru dalam suatu proyek untuk mempelajari proyek tersebut, yang berarti peningkatan jumlah jam kerja tanpa hasil sama sekali.
  6. Ini sering mengarah pada duplikasi kode. Akhirnya blok, meskipun ini tidak sepenuhnya diperlukan, perlu menyelesaikan semua pointer menggantung yang dibiarkan terbuka oleh blok coba yang terganggu. Jadi, cobalah blok. Ini berarti Anda dapat memiliki try{ obj.openSomething(); /*something which causes exception*/ obj.doStuff(); obj.closeSomething();}catch(Exception e){obj.closeSomething();}. Dalam if...elseskenario yang lebih tradisional, closeSomething()kemungkinannya kecil (sekali lagi, pengalaman pribadi) menjadi pekerjaan salin dan tempel. (Harus diakui, argumen khusus ini lebih berkaitan dengan orang-orang yang saya temui daripada filsafat itu sendiri).
cwallenpoole
sumber
AFAIK, # 6 adalah masalah hanya di Jawa, yang, tidak seperti bahasa modern lainnya, tidak memiliki penutupan atau manajemen sumber daya berbasis stack. Ini tentu saja bukan masalah yang melekat dalam penggunaan pengecualian.
kevin cline
4 dan 5 tampaknya menjadi poin yang sama bagi saya. 3-6 tidak berlaku jika bahasa Anda adalah python. 1 dan 2 adalah masalah potensial, tetapi saya pikir mereka ditangani dengan meminimalkan kode di blok percobaan.
Winston Ewert
1
@ Winston saya tidak setuju. 1 dan 2 adalah masalah utama yang, meskipun dihilangkan oleh standar pengkodean yang lebih baik, masih membuat orang bertanya-tanya apakah mungkin tidak lebih baik untuk menghindari potensi kesalahan untuk memulai. 3 berlaku jika bahasa Anda adalah Python. 4-5 juga dapat berlaku untuk Python tetapi tidak harus. 4 dan 5 adalah poin yang sangat berbeda - menyesatkan berbeda dari perbedaan gaya. Kode yang menyesatkan mungkin melakukan sesuatu seperti memberi nama pelatuk untuk memulai kendaraan, "tombol berhenti". Secara gaya, di sisi lain, bisa juga analog dengan menghindari semua lekukan blok di C.
cwallenpoole
3) Python memiliki blok lain untuk pengecualian. Ini sangat membantu untuk menghindari masalah yang biasanya Anda dapatkan untuk 1 dan 2.
Winston Ewert
1
Untuk lebih jelasnya, saya tidak menganjurkan menggunakan pengecualian adalah mekanisme kontrol aliran umum Anda. Saya menganjurkan melemparkan pengecualian untuk segala jenis "kegagalan" mode tidak peduli seberapa kecil. Saya pikir versi penanganan pengecualian lebih bersih dan kecil kemungkinannya untuk menyembunyikan bug daripada versi pengecekan nilai balik. Dan idealnya, saya ingin bahasa membuatnya lebih sulit untuk menangkap kesalahan bersarang.
Winston Ewert
4

Argumen utama saya adalah bahwa menggunakan try / catch for logic memecah aliran logis. Mengikuti "logika" melalui konstruksi non-logika adalah (bagi saya) kontra-intuitif dan membingungkan. Saya terbiasa membaca logika saya sebagai "jika Kondisikan maka A lain B". Membaca pernyataan yang sama dengan "Coba tangkapan lalu jalankan B" terasa aneh. Akan lebih aneh lagi jika pernyataan Aadalah penugasan sederhana, membutuhkan kode tambahan untuk memaksa pengecualian jika conditionsalah (dan melakukan itu mungkin akan memerlukan ifpernyataan-toh).

FrustratedWithFormsDesigner
sumber
2

Nah, hanya soal etiket, sebelum "memulai pertengkaran dengan mereka", seperti yang Anda nyatakan, saya akan bertanya, "Mengapa mereka menggunakan penanganan perkecualian di semua tempat yang berbeda ini?"

Maksud saya, ada beberapa kemungkinan:

  1. mereka tidak kompeten
  2. ada alasan yang benar-benar valid untuk apa yang mereka lakukan, yang mungkin tidak muncul pada pandangan pertama.
  3. kadang-kadang itu masalah selera dan dapat menyederhanakan beberapa aliran program yang kompleks.
  4. Itu adalah peninggalan masa lalu yang belum ada yang berubah dan mereka akan senang jika seseorang melakukannya

... Saya pikir semua ini sama-sama mungkin. Jadi tanyakan saja kepada mereka dengan baik.

dagnelies
sumber
1

Try Catch seharusnya hanya digunakan untuk penanganan pengecualian. Lebih dari itu, penanganan pengecualian khusus. Tangkapan uji coba Anda seharusnya hanya menangkap pengecualian yang diharapkan, selain itu tidak terbentuk dengan baik. Jika Anda perlu menggunakan tangkapan semua mencoba menangkap, maka Anda mungkin melakukan sesuatu yang salah.

EDIT:

Alasan: Anda dapat berargumen bahwa jika Anda menggunakan try catch sebagai operator bersyarat, Bagaimana Anda akan memperhitungkan pengecualian NYATA?

AJC
sumber
2
OP menanyakan alasan / argumen. Anda belum memberikan.
Oded
"Anda bisa membantah bahwa jika Anda menggunakan try catch sebagai operator bersyarat, Bagaimana Anda akan memperhitungkan pengecualian NYATA?" - Dengan menangkap pengecualian nyata dalam catchklausa yang berbeda dari yang menangkap pengecualian "tidak nyata"?
@delnan - Terima kasih! Anda telah membuktikan poin yang akan saya sampaikan. Jika seseorang menjawab apa yang baru saja Anda katakan dengan alasan saya dan Oded saya hanya akan berhenti berbicara karena dia tidak mencari alasan dia hanya keras kepala dan saya tidak membuang waktu saya dengan keras kepala.
AJC
Anda memanggil saya anak perempuan karena saya menunjukkan kekurangan dalam beberapa argumen yang tercantum di sini? Perhatikan bagaimana saya tidak bisa mengatakan apa pun terhadap poin-poin lain yang dinyatakan di sini. Saya bukan penggemar menggunakan pengecualian untuk kontrol aliran (meskipun saya tidak akan mengecam apa pun baik tanpa detail, maka permintaan saya untuk elaborasi oleh OP), saya hanya bermain advokat iblis.
1
Menggunakan try-catch sebagai operator kondisional sama sekali tidak mencegahnya bekerja dan juga menangkap pengecualian "nyata".
Winston Ewert
1

Pengecualian adalah untuk saat hal luar biasa terjadi. Apakah program berfungsi sesuai dengan alur kerja biasa luar biasa?

jfrobishow
sumber
1
Tapi kenapa? Inti pertanyaannya adalah mengapa (atau mengapa tidak) pengecualian hanya baik untuk itu.
Winston Ewert
Tidak selalu "luar biasa". Misalnya, tidak menemukan kunci dalam hashtable tidak terlalu luar biasa, namun perpustakaan OCaml cenderung memunculkan pengecualian dalam kasus-kasus seperti itu. Dan itu ok - penanganan pengecualian sangat murah di sana.
SK-logic
1
-1: pernyataan tautologis
Kue Tepung Beras
1

Alasan menggunakan pengecualian:

  1. Jika Anda lupa menangkap keadaan luar biasa, program Anda akan mati dan jejak tumpukan akan memberi tahu Anda alasannya. Jika Anda lupa untuk menangani nilai pengembalian untuk keadaan pengecualian tidak ada yang mengatakan seberapa jauh program Anda akan menunjukkan perilaku yang salah.
  2. Menggunakan nilai balik hanya berfungsi jika ada nilai sentinel yang dapat Anda kembalikan. Jika semua nilai pengembalian yang mungkin sudah valid, apa yang akan Anda lakukan?
  3. Pengecualian akan membawa informasi tambahan tentang apa yang terjadi yang mungkin bermanfaat.

Alasan untuk tidak menggunakan pengecualian:

  1. Banyak bahasa tidak dirancang untuk membuat pengecualian dengan cepat.
  2. Pengecualian yang berjalan beberapa lapisan ke atas tumpukan dapat menyebabkan kondisi tidak konsisten di belakangnya

Pada akhirnya:

Tujuannya adalah menulis kode yang mengkomunikasikan apa yang sedang terjadi. Pengecualian dapat membantu / menghalangi hal itu tergantung pada apa yang dilakukan kode. Coba / tangkap dengan python untuk KeyError pada referensi kamus sempurna (selama Anda tahu bahasa) coba / tangkap untuk KeyError yang sama lima fungsi lapisan jauh itu berbahaya.

Winston Ewert
sumber
0

Saya menggunakan try-> catch sebagai kontrol aliran dalam situasi tertentu. Jika logika utama Anda bergantung pada sesuatu yang gagal, tetapi Anda tidak ingin hanya melemparkan pengecualian dan berhenti ... Itulah gunanya mencoba-> catch block. Saya menulis banyak skrip unix server-side unmonitored, dan jauh lebih penting bagi mereka untuk tidak gagal, daripada bagi mereka untuk gagal dengan cantik.

Jadi coba Paket A, dan jika Paket A mati, tangkap dan jalankan dengan Paket B ... Dan jika paket B gagal, gunakan akhirnya untuk memulai Paket C, yang akan memperbaiki salah satu layanan yang gagal di A atau B, atau halaman saya.

Satanicpuppy
sumber
0

Itu tergantung pada bahasa dan mungkin pada implementasi yang digunakan. Standar dalam C ++ adalah bahwa pengecualian harus disimpan untuk acara yang benar-benar luar biasa. Di sisi lain, dalam Python salah satu pedoman adalah " lebih mudah untuk meminta maaf daripada izin ", sehingga integrasi coba / kecuali blok dalam logika program dianjurkan.

Charles E. Grant
sumber
"Standar dalam C ++ adalah bahwa pengecualian harus disimpan untuk acara yang benar-benar luar biasa." Ini tidak masuk akal. Bahkan penemu bahasa tidak setuju dengan Anda .
arayq2
-1

Ini kebiasaan buruk, tapi saya melakukannya dari waktu ke waktu dengan python. Seperti daripada memeriksa untuk melihat apakah ada file, saya hanya mencoba dan menghapusnya. Jika itu melempar pengecualian, saya menangkap dan terus mengetahui bahwa itu tidak ada. <== (belum tentu benar jika pengguna lain memiliki file tersebut, tetapi saya melakukannya di direktori home pengguna sehingga ini TIDAK HARUS terjadi).

Namun, terlalu sering menggunakannya adalah praktik yang buruk.

RobotHumans
sumber
3
Dalam contoh itu, menggunakan pengecualian alih-alih "melihat sebelum Anda melompat" sebenarnya adalah ide yang bagus: Ini menghindari kondisi balapan. Pemeriksaan untuk ketersediaan file (keberadaan, izin, tidak dikunci) berhasil tidak berarti nanti - bahkan jika itu hanya beberapa opcode kemudian - akses (membuka, menghapus, memindahkan, mengunci, apa pun) akan berhasil, karena file dapat diubah (dihapus, dipindahkan, minta izinnya diubah) di antaranya.
Jika python melempar pengecualian hanya karena file tidak ada, tampaknya mendorong kebiasaan buruk, seperti yang dijelaskan delnan.
Per Johansson
@delnan: Meskipun benar, IMHO jika berlari ke kondisi balapan seperti itu mungkin, Anda harus memikirkan kembali desain Anda. Dalam kasus seperti itu, jelas tidak ada pemisahan kekhawatiran di sistem Anda. Kecuali jika Anda memiliki alasan yang sangat baik untuk melakukan hal-hal seperti itu, Anda harus menyatukan akses di pihak Anda, atau menggunakan database yang tepat untuk menangani banyak klien yang mencoba melakukan transaksi pada data persisten yang sama.
back2dos
1
Ini bukan kebiasaan buruk. Ini gaya yang direkomendasikan dalam Python.
Winston Ewert
@ back2dos, dapatkah Anda mencegahnya ketika berhadapan dengan sumber daya eksternal seperti pengguna lain dari sistem basis data / file?
Winston Ewert
-1

Saya suka cara Apple mendefinisikannya : Pengecualian hanya untuk kesalahan pemrogram dan kesalahan runtime yang fatal. Gunakan kode kesalahan lain. Ini membantu saya untuk memutuskan kapan menggunakannya, berpikir dalam hati, "Apakah ini kesalahan programmer?"

Per Johansson
sumber