MethodA memanggil MethodB yang pada gilirannya memanggil MethodC.
Tidak ada penanganan eksepsi di MethodB atau MethodC. Tetapi ada penanganan pengecualian di MethodA.
Dalam MethodC terjadi pengecualian.
Sekarang, pengecualian itu menggelembung ke MethodA, yang menanganinya dengan tepat.
apa yang salah dengan ini?
Dalam pikiran saya, pada titik tertentu penelepon akan mengeksekusi MethodB atau MethodC, dan ketika pengecualian memang terjadi dalam metode tersebut, apa yang akan diperoleh dari penanganan pengecualian di dalam metode tersebut, yang pada dasarnya hanyalah blok coba / tangkap / akhirnya bukannya membiarkan mereka menggembung sampai ke callee?
Pernyataan atau konsensus seputar penanganan pengecualian adalah untuk membuang ketika eksekusi tidak dapat dilanjutkan hanya karena itu - pengecualian. Saya mengerti. Tapi mengapa tidak menangkap pengecualian lebih jauh dari rantai daripada mencoba / menangkap blok sepanjang jalan.
Saya mengerti ketika Anda perlu membebaskan sumber daya. Itu masalah yang sama sekali berbeda.
sumber
try-catch
blok.Result<T>
tipe (tipe yang menyimpan hasil dari perhitungan, atau kesalahan), dan mengembalikannya dari fungsi melempar Anda yang sebaliknya. Menyebarkan kesalahan di tumpukan akan berarti membaca setiap nilai kembali, memeriksa apakah itu kesalahan, dan mengembalikan kesalahan jika demikian.Jawaban:
Sebagai prinsip umum, jangan menangkap pengecualian kecuali Anda tahu apa yang harus dilakukan dengan mereka. Jika MethodC melempar pengecualian, tetapi MethodB tidak memiliki cara yang berguna untuk menanganinya, maka MethodC akan memungkinkan pengecualian menyebar ke MethodA.
Satu-satunya alasan mengapa suatu metode harus memiliki mekanisme penangkapan dan rethrow adalah:
Kalau tidak, menangkap pengecualian di tingkat yang salah cenderung menghasilkan kode yang gagal secara diam-diam tanpa memberikan umpan balik yang berguna ke kode panggilan (dan akhirnya pengguna perangkat lunak). Alternatif menangkap pengecualian dan kemudian segera memikirkan kembali tidak ada gunanya.
sumber
try ... finally ...
, kemudian gunakan itu, bukan catch & rethrowLoadDataException
dan sertakan detail pengecualian asli sesuai dengan fitur bahasa Anda, sehingga pengelola masa depan dapat melihat akar penyebabnya tanpa harus melampirkan debugger dan mencari tahu cara mereproduksi masalah.Sama sekali tidak ada.
"menanganinya dengan tepat" adalah bagian yang penting. Itulah inti dari Penanganan Eksepsi Terstruktur.
Jika kode Anda dapat melakukan sesuatu yang "berguna" dengan Pengecualian, lakukan saja. Jika tidak, maka biarkan saja.
Itulah yang seharusnya Anda lakukan. Jika Anda membaca kode yang memiliki handler / rethrowers "all down", maka Anda [mungkin] membaca beberapa kode yang sangat buruk.
Sayangnya, beberapa Pengembang hanya melihat catch block sebagai kode "boiler-plate" yang mereka masukkan (tidak ada permainan kata-kata) untuk setiap metode yang mereka tulis, sering kali karena mereka tidak benar-benar "mendapatkan" Penanganan Pengecualian dan berpikir mereka harus menambahkan sesuatu sehingga bahwa Pengecualian tidak "melarikan diri" dan mematikan program mereka.
Bagian dari kesulitan di sini adalah bahwa, sebagian besar waktu, masalah ini bahkan tidak akan diperhatikan, karena Pengecualian tidak selalu dilemparkan tetapi, ketika itu terjadi , program ini akan membuang banyak sekali waktu dan upaya secara bertahap membuka tumpukan panggilan untuk bangun ke suatu tempat yang benar-benar melakukan sesuatu yang berguna dengan Pengecualian.
sumber
catch
di tingkat tertinggi yang memungkinkan untuk mencatat kesalahan dan mengembalikan respons kesalahan. Tidak adacatch
balok yang ditaburkan di mana-mana. Jika Anda merasa tidak ingin mencantumkan setiap pengecualian yang mungkin diperiksa (dalam bahasa seperti Java), cukup bungkus dalam,RuntimeException
alih - alih mencatatnya di sana, mencoba melanjutkan, dan mengalami lebih banyak kesalahan atau bahkan kerentanan.Anda harus membuat perbedaan antara Perpustakaan dan Aplikasi.
Perpustakaan dapat membuang pengecualian tanpa tertangkap secara bebas
Saat Anda mendesain perpustakaan, pada titik tertentu Anda harus memikirkan apa yang salah. Parameter bisa berada dalam kisaran yang salah atau
null
, sumber daya eksternal tidak tersedia, dll.Pustaka Anda paling sering tidak memiliki cara untuk menghadapinya dengan cara yang masuk akal . Satu-satunya solusi yang masuk akal adalah dengan melemparkan Pengecualian yang sesuai dan membiarkan pengembang Aplikasi menanganinya.
Aplikasi harus selalu pada beberapa titik menangkap pengecualian
Ketika Pengecualian ditangkap, saya suka mengategorikannya sebagai Kesalahan atau Kesalahan Fatal . Kesalahan reguler berarti bahwa satu operasi dalam Aplikasi saya gagal. Misalnya, dokumen terbuka tidak dapat disimpan, karena tujuannya tidak dapat ditulis. Satu-satunya pemikiran yang masuk akal untuk dilakukan Aplikasi adalah memberi tahu pengguna bahwa operasi tidak dapat diselesaikan dengan sukses, memberikan informasi yang dapat dibaca manusia sehubungan dengan masalah tersebut dan kemudian membiarkan pengguna memutuskan apa yang harus dilakukan selanjutnya.
Sebuah Kesalahan Fatal adalah kesalahan logika Aplikasi utama tidak dapat pulih dari. Sebagai contoh, jika driver perangkat grafis crash dalam permainan video, tidak ada cara bagi Aplikasi untuk "dengan anggun" menginformasikan pengguna. Dalam hal ini, file log harus ditulis dan, jika mungkin, pengguna harus diberitahu dengan cara apa pun.
Bahkan dalam kasus yang parah, Aplikasi harus menangani Pengecualian ini dengan cara yang berarti. Ini mungkin termasuk menulis file Log, mengirimkan Laporan Kecelakaan, dll. Tidak ada alasan bagi Aplikasi untuk tidak menanggapi Pengecualian dalam beberapa cara.
sumber
HDDPluggedOutDuringWritingException
dapat ditangani dan tidak fatal untuk aplikasi tersebut. Program dapat memutuskan apa yang harus dilakukan dengan itu.Apa yang salah dengan pola yang Anda gambarkan adalah bahwa metode A tidak akan dapat membedakan antara tiga skenario:
Metode B gagal dengan cara yang diantisipasi.
Metode C gagal dengan cara yang tidak diantisipasi oleh metode B, tetapi sementara metode B sedang melakukan operasi yang bisa ditinggalkan dengan aman.
Metode C gagal dengan cara yang tidak diantisipasi oleh metode B, tetapi sementara metode B sedang melakukan operasi yang menempatkan hal-hal dalam keadaan tidak koheren yang semestinya sementara yang gagal dibersihkan oleh B karena kegagalan C.
Satu-satunya cara metode A akan dapat membedakan skenario-skenario itu adalah jika pengecualian yang dilemparkan dari B mencakup informasi yang cukup untuk tujuan itu, atau jika tumpukan yang membuka gulungan untuk metode B menyebabkan objek dibiarkan dalam keadaan tidak valid secara eksplisit . Sayangnya, sebagian besar kerangka kerja pengecualian membuat kedua pola ini canggung, memaksa pemrogram untuk membuat keputusan desain yang "kurang jahat".
sumber