Dalam hal-hal tingkat tinggi, pengecualian; dalam hal-hal tingkat rendah, kode kesalahan.
Perilaku default dari pengecualian adalah untuk melepas tumpukan dan menghentikan program, jika saya menulis skrip dan saya mencari kunci yang tidak ada dalam kamus, itu mungkin kesalahan, dan saya ingin program berhenti dan biarkan saya tahu semua tentang itu.
Namun, jika saya menulis sepotong kode yang harus saya ketahui perilakunya dalam setiap situasi yang memungkinkan, maka saya menginginkan kode kesalahan. Kalau tidak, saya harus mengetahui setiap pengecualian yang dapat dilemparkan oleh setiap baris dalam fungsi saya untuk mengetahui apa yang akan dilakukannya (Baca Pengecualian yang Membumikan Maskapai untuk mengetahui betapa rumitnya hal ini). Membosankan dan sulit untuk menulis kode yang bereaksi dengan tepat untuk setiap situasi (termasuk yang tidak menyenangkan), tetapi itu karena menulis kode bebas kesalahan itu membosankan dan sulit, bukan karena Anda mengirimkan kode kesalahan.
Baik Raymond Chen dan Joel telah membuat beberapa argumen fasih yang menentang penggunaan pengecualian untuk segala hal.
nodiscard
atribut yang akan memberikan peringatan compiler jika nilai kembali dari suatu fungsi tidak disimpan. Membantu sedikit untuk menangkap pengecekan kode kesalahan yang terlupakan. Contoh: godbolt.org/g/6i6E0BSaya biasanya lebih suka pengecualian, karena mereka memiliki informasi yang lebih kontekstual dan dapat menyampaikan (jika digunakan dengan benar) kesalahan kepada programmer dengan cara yang lebih jelas.
Di sisi lain, kode kesalahan lebih ringan daripada pengecualian tetapi lebih sulit untuk dipertahankan. Pemeriksaan kesalahan dapat dihilangkan secara tidak sengaja. Kode kesalahan lebih sulit untuk dipertahankan karena Anda harus menyimpan katalog dengan semua kode kesalahan dan kemudian mengaktifkan hasilnya untuk melihat kesalahan apa yang terjadi. Rentang kesalahan dapat membantu di sini, karena jika satu-satunya hal yang kita minati adalah apakah kita ada kesalahan atau tidak, lebih mudah untuk memeriksanya (misalnya, kode kesalahan HRESULT lebih besar atau sama dengan 0 adalah berhasil dan kurang dari nol adalah kegagalan). Mereka dapat secara tidak sengaja dihilangkan karena tidak ada pemaksaan terprogram yang akan diperiksa oleh pengembang untuk kode kesalahan. Di sisi lain, Anda tidak dapat mengabaikan pengecualian.
Untuk meringkas saya lebih suka pengecualian atas kode kesalahan di hampir semua situasi.
sumber
Saya lebih suka pengecualian karena
sumber
goto
Kode kesalahan dapat diabaikan (dan seringkali!) Oleh pemanggil fungsi Anda. Pengecualian setidaknya memaksa mereka untuk menangani kesalahan dengan cara tertentu. Bahkan jika versi mereka untuk menghadapinya adalah memiliki penangan tangkapan kosong (menghela nafas).
sumber
Pengecualian atas kode kesalahan, tidak diragukan lagi. Anda mendapatkan banyak manfaat yang sama dari pengecualian seperti yang Anda dapatkan dengan kode kesalahan, tetapi juga lebih banyak lagi, tanpa kekurangan kode kesalahan. Satu-satunya pengecualian adalah bahwa itu sedikit lebih overhead; tetapi di zaman sekarang ini, overhead tersebut harus dianggap dapat diabaikan untuk hampir semua aplikasi.
Berikut beberapa artikel yang membahas, membandingkan, dan membedakan kedua teknik tersebut:
Ada beberapa tautan bagus di dalamnya yang dapat memberi Anda bacaan lebih lanjut.
sumber
Saya tidak akan pernah mencampur dua model ... terlalu sulit untuk mengonversi dari satu ke yang lain saat Anda berpindah dari satu bagian tumpukan yang menggunakan kode kesalahan, ke bagian yang lebih tinggi yang menggunakan pengecualian.
Pengecualian adalah untuk "segala sesuatu yang menghentikan atau menghambat metode atau subrutin melakukan apa yang Anda minta" ... TIDAK memberikan pesan balik tentang penyimpangan atau keadaan yang tidak biasa, atau status sistem, dll. Gunakan nilai atau ref (atau keluar) parameter untuk itu.
Pengecualian memungkinkan metode untuk ditulis (dan digunakan) dengan semantik yang bergantung pada fungsi metode, yaitu metode yang mengembalikan objek Karyawan atau Daftar Karyawan dapat diketik untuk melakukan hal itu, dan Anda dapat menggunakannya dengan memanggil.
Dengan kode kesalahan, semua metode mengembalikan kode kesalahan, jadi, bagi mereka yang perlu mengembalikan sesuatu yang lain untuk digunakan oleh kode panggilan, Anda harus meneruskan variabel referensi untuk diisi dengan data itu, dan menguji nilai kembali untuk kode kesalahan, dan menanganinya, pada setiap pemanggilan fungsi atau metode.
Jika Anda membuat kode sehingga setiap metode melakukan satu dan hanya satu hal sederhana, Anda harus memberikan pengecualian setiap kali metode tidak dapat mencapai tujuan yang diinginkan dari metode tersebut. Pengecualian jauh lebih kaya dan lebih mudah digunakan dengan cara ini daripada kode kesalahan. Kode Anda jauh lebih bersih - Alur standar dari jalur kode "normal" dapat dikhususkan hanya untuk kasus di mana metode IS dapat mencapai apa yang Anda inginkan ... Dan kemudian kode untuk membersihkan, atau menangani keadaan "luar biasa" ketika sesuatu yang buruk terjadi yang mencegah metode menyelesaikan dengan sukses dapat disingkirkan dari kode normal. Selain itu, jika Anda tidak dapat menangani pengecualian di tempat terjadinya, dan harus meneruskan tumpukan ke UI, (atau lebih buruk, melintasi kabel dari komponen tingkat menengah ke UI), maka dengan model pengecualian,
sumber
Di masa lalu saya bergabung dengan kamp kode kesalahan (melakukan terlalu banyak pemrograman C). Tapi sekarang saya telah melihat cahaya.
Ya, pengecualian sedikit membebani sistem. Tetapi mereka menyederhanakan kode, mengurangi jumlah kesalahan (dan WTF).
Jadi gunakan pengecualian tetapi gunakan dengan bijak. Dan mereka akan menjadi temanmu.
Sebagai catatan tambahan. Saya telah belajar untuk mendokumentasikan pengecualian mana yang dapat dilemparkan dengan metode mana. Sayangnya ini tidak diperlukan oleh kebanyakan bahasa. Namun, hal itu meningkatkan peluang penanganan pengecualian yang tepat di tingkat yang tepat.
sumber
Mungkin ada beberapa situasi di mana menggunakan pengecualian dengan cara yang bersih, jelas, dan benar tidak praktis, tetapi sebagian besar pengecualian waktu adalah pilihan yang jelas. Penanganan pengecualian manfaat terbesar memiliki lebih dari kode kesalahan adalah mengubah aliran eksekusi, yang penting karena dua alasan.
Ketika pengecualian terjadi, aplikasi tidak lagi mengikuti jalur eksekusi 'normal' itu. Alasan pertama mengapa ini begitu penting adalah bahwa kecuali pembuat kode berjalan dengan baik dan benar-benar keluar dari jalan mereka untuk menjadi buruk, program akan berhenti dan tidak terus melakukan hal-hal yang tidak terduga. Jika kode kesalahan tidak diperiksa dan tindakan yang tepat tidak diambil sebagai tanggapan atas kode kesalahan yang buruk, program akan terus melakukan apa yang dilakukannya dan siapa yang tahu apa hasil dari tindakan itu. Ada banyak situasi di mana membuat program melakukan 'apapun' bisa menjadi sangat mahal. Pertimbangkan program yang mengambil informasi kinerja untuk berbagai instrumen keuangan yang dijual perusahaan, dan mengirimkan informasi tersebut ke pialang / grosir. Jika terjadi kesalahan dan program terus berjalan, itu dapat mengirimkan data kinerja yang salah ke pialang dan grosir. Saya tidak tahu tentang orang lain, tetapi saya tidak ingin menjadi orang yang duduk di kantor VP menjelaskan mengapa kode saya menyebabkan perusahaan mendapatkan denda peraturan senilai 7 digit. Menyampaikan pesan kesalahan kepada pelanggan umumnya lebih baik daripada mengirimkan data yang salah yang mungkin terlihat 'nyata', dan situasi terakhir jauh lebih mudah untuk dihadapi dengan pendekatan yang jauh lebih tidak agresif seperti kode kesalahan.
Alasan kedua mengapa saya menyukai pengecualian dan pemutusan eksekusi normal mereka adalah karena itu membuatnya jauh, lebih mudah untuk menjaga logika 'hal-hal normal sedang terjadi' terpisah dari 'logika sesuatu yang salah'. Bagi saya, ini:
... lebih disukai daripada ini:
Ada hal-hal kecil lainnya tentang pengecualian yang bagus juga. Memiliki sekumpulan logika kondisional untuk melacak apakah salah satu metode yang dipanggil dalam suatu fungsi memiliki kode kesalahan yang dikembalikan, dan mengembalikan kode kesalahan itu lebih tinggi adalah banyak pelat boiler. Faktanya, banyak pelat boiler yang bisa salah. Saya memiliki lebih banyak kepercayaan pada sistem pengecualian dari sebagian besar bahasa daripada yang saya lakukan pada sarang tikus pernyataan if-else-if-else yang ditulis Fred 'Fresh-out-of-college', dan saya memiliki banyak hal yang lebih baik untuk dilakukan dengan waktu saya daripada meninjau kode kata sarang tikus.
sumber
Anda harus menggunakan keduanya. Masalahnya adalah memutuskan kapan akan menggunakan masing-masing .
Ada beberapa skenario di mana pengecualian adalah pilihan yang jelas :
Dalam beberapa situasi Anda tidak dapat melakukan apa pun dengan kode kesalahan , dan Anda hanya perlu menanganinya di tingkat atas dalam tumpukan panggilan , biasanya hanya mencatat kesalahan, menampilkan sesuatu kepada pengguna atau menutup program. Dalam kasus ini, kode kesalahan akan meminta Anda untuk menggelembung kode kesalahan secara manual tingkat demi tingkat yang jelas lebih mudah dilakukan dengan pengecualian. Intinya adalah ini untuk situasi yang tidak terduga dan tidak dapat ditangani .
Namun tentang situasi 1 (di mana terjadi sesuatu yang tidak terduga dan tidak dapat ditangani, Anda tidak ingin mencatatnya), pengecualian dapat berguna karena Anda dapat menambahkan informasi kontekstual . Misalnya jika saya mendapatkan SqlException di pembantu data tingkat rendah saya, saya ingin menangkap kesalahan itu di tingkat rendah (di mana saya tahu perintah SQL yang menyebabkan kesalahan) sehingga saya dapat menangkap informasi itu dan menelusuri kembali dengan informasi tambahan . Harap perhatikan kata ajaib di sini: lempar ulang, dan jangan menelan . Aturan pertama penanganan pengecualian: jangan menelan pengecualian . Juga, perhatikan bahwa tangkapan dalam saya tidak perlu mencatat apa pun karena tangkapan luar akan memiliki seluruh jejak tumpukan dan dapat mencatatnya.
Dalam beberapa situasi Anda memiliki urutan perintah, dan jika ada yang gagal Anda harus membersihkan / membuang sumber daya (*), apakah ini adalah situasi yang tidak dapat dipulihkan (yang harus dilempar) atau situasi yang dapat dipulihkan (dalam hal ini Anda dapat menangani secara lokal atau dalam kode penelepon tetapi Anda tidak memerlukan pengecualian). Jelas jauh lebih mudah untuk meletakkan semua perintah itu dalam sekali percobaan, daripada menguji kode kesalahan setelah setiap metode, dan membersihkan / membuang di blok terakhir. Harap dicatat bahwa jika Anda ingin kesalahan meluap (yang mungkin Anda inginkan), Anda bahkan tidak perlu menangkapnya - Anda cukup menggunakan akhirnya untuk pembersihan / pembuangan - Anda hanya boleh menggunakan tangkap / retrow jika Anda mau untuk menambahkan informasi kontekstual (lihat poin 2).
Salah satu contohnya adalah urutan pernyataan SQL di dalam blok transaksi. Sekali lagi, ini juga merupakan situasi yang "tidak dapat ditangani", bahkan jika Anda memutuskan untuk mengetahuinya lebih awal (perlakukan secara lokal alih-alih membesar-besarkan) itu masih merupakan situasi yang fatal di mana hasil terbaik adalah membatalkan semuanya atau setidaknya menggugurkan bagian dari proses.
(*) Ini seperti
on error goto
yang kami gunakan di Visual Basic lamaDalam konstruktor, Anda hanya bisa melempar pengecualian.
Karena itu, dalam semua situasi lain di mana Anda mengembalikan beberapa informasi yang penelepon DAPAT / HARUS mengambil tindakan , menggunakan kode pengembalian mungkin merupakan alternatif yang lebih baik. Ini mencakup semua "error" yang diharapkan , karena mungkin error tersebut harus ditangani oleh pemanggil langsung, dan hampir tidak perlu dinaikkan terlalu banyak level di stack.
Tentu saja selalu mungkin untuk memperlakukan kesalahan yang diharapkan sebagai pengecualian, dan menangkap kemudian segera satu tingkat di atas, dan itu juga mungkin untuk mencakup setiap baris kode dalam coba tangkap dan mengambil tindakan untuk setiap kesalahan yang mungkin terjadi. IMO, ini adalah desain yang buruk, tidak hanya karena jauh lebih bertele-tele, tetapi khususnya karena kemungkinan pengecualian yang mungkin dilemparkan tidak jelas tanpa membaca kode sumber - dan pengecualian dapat dilemparkan dari metode dalam apa pun, menciptakan gotos yang tidak terlihat . Mereka merusak struktur kode dengan membuat beberapa titik keluar tak terlihat yang membuat kode sulit dibaca dan diperiksa. Dengan kata lain, Anda tidak boleh menggunakan pengecualian sebagai kontrol aliran, karena akan sulit bagi orang lain untuk memahami dan memeliharanya. Bahkan bisa menjadi sulit untuk memahami semua aliran kode yang mungkin untuk pengujian.
Sekali lagi: untuk pembersihan / pembuangan yang benar, Anda dapat menggunakan try-akhirnya tanpa menangkap apa pun .
Kritik paling populer tentang kode pengembalian adalah bahwa "seseorang dapat mengabaikan kode kesalahan, tetapi dalam arti yang sama seseorang juga dapat menelan pengecualian. Penanganan pengecualian yang buruk mudah dilakukan di kedua metode. Tetapi menulis program berbasis kode kesalahan yang baik masih jauh lebih mudah daripada menulis program berbasis pengecualian . Dan jika seseorang dengan alasan apa pun memutuskan untuk mengabaikan semua kesalahan (yang lama
on error resume next
), Anda dapat dengan mudah melakukannya dengan kode yang dikembalikan dan Anda tidak dapat melakukannya tanpa banyak uji coba tangkap.Kritik paling populer kedua tentang kode pengembalian adalah bahwa "sulit untuk meluap" - tetapi itu karena orang tidak memahami bahwa pengecualian adalah untuk situasi yang tidak dapat dipulihkan, sedangkan kode kesalahan tidak.
Memutuskan antara pengecualian dan kode kesalahan adalah area abu-abu. Bahkan mungkin saja Anda perlu mendapatkan kode kesalahan dari beberapa metode bisnis yang dapat digunakan kembali, dan kemudian Anda memutuskan untuk menggabungkannya menjadi pengecualian (mungkin menambahkan informasi) dan membiarkannya menggelembung. Tapi itu adalah kesalahan desain untuk berasumsi bahwa SEMUA kesalahan harus dilemparkan sebagai pengecualian.
Singkatnya:
Saya suka menggunakan pengecualian ketika saya mengalami situasi yang tidak terduga, di mana tidak banyak yang harus dilakukan, dan biasanya kami ingin membatalkan blok kode yang besar atau bahkan seluruh operasi atau program. Ini seperti yang lama "pada kesalahan goto".
Saya suka menggunakan kode pengembalian ketika saya mengharapkan situasi di mana kode penelepon dapat / harus mengambil tindakan. Ini mencakup sebagian besar metode bisnis, API, validasi, dan sebagainya.
Perbedaan antara kode pengecualian dan kesalahan ini adalah salah satu prinsip desain bahasa GO, yang menggunakan "panik" untuk situasi tak terduga yang fatal, sementara situasi biasa yang diharapkan dikembalikan sebagai kesalahan.
Namun tentang GO, ini juga memungkinkan beberapa nilai kembali , yang merupakan sesuatu yang sangat membantu dalam menggunakan kode pengembalian, karena Anda dapat secara bersamaan mengembalikan kesalahan dan hal lain. Di C # / Java kita dapat mencapainya tanpa parameter, Tuple, atau Generik (favorit saya), yang dikombinasikan dengan enum dapat memberikan kode kesalahan yang jelas kepada pemanggil:
Jika saya menambahkan kemungkinan pengembalian baru dalam metode saya, saya bahkan dapat memeriksa semua pemanggil jika mereka mencakup nilai baru itu dalam pernyataan sakelar misalnya. Anda benar-benar tidak dapat melakukannya dengan pengecualian. Saat Anda menggunakan kode pengembalian, Anda biasanya akan mengetahui terlebih dahulu semua kemungkinan kesalahan, dan mengujinya. Dengan pengecualian, Anda biasanya tidak tahu apa yang mungkin terjadi. Membungkus enum di dalam pengecualian (bukan Generik) adalah alternatif (selama jelas jenis pengecualian yang akan dilemparkan setiap metode), tetapi IMO itu masih desain yang buruk.
sumber
Alasan saya adalah jika Anda menulis driver tingkat rendah yang benar-benar membutuhkan kinerja, gunakan kode kesalahan. Tetapi jika Anda menggunakan kode itu dalam aplikasi tingkat yang lebih tinggi dan dapat menangani sedikit overhead, maka bungkus kode itu dengan antarmuka yang memeriksa kode kesalahan tersebut dan memunculkan pengecualian.
Dalam semua kasus lainnya, pengecualian mungkin merupakan cara yang tepat.
sumber
Saya mungkin duduk di pagar di sini, tapi ...
Di Python, penggunaan pengecualian adalah praktik standar, dan saya cukup senang untuk mendefinisikan pengecualian saya sendiri. Di C Anda tidak memiliki pengecualian sama sekali.
Dalam C ++ (setidaknya di STL), pengecualian biasanya hanya diberikan untuk kesalahan yang benar-benar luar biasa (saya sendiri sebenarnya tidak pernah melihatnya). Saya tidak melihat alasan untuk melakukan sesuatu yang berbeda dalam kode saya sendiri. Ya, mudah untuk mengabaikan nilai yang dikembalikan, tetapi C ++ juga tidak memaksa Anda untuk menangkap pengecualian. Saya pikir Anda hanya perlu membiasakan diri melakukannya.
Basis kode yang saya kerjakan sebagian besar adalah C ++ dan kami menggunakan kode kesalahan hampir di mana-mana, tetapi ada satu modul yang menimbulkan pengecualian untuk kesalahan apa pun, termasuk yang sangat tidak terkecuali, dan semua kode yang menggunakan modul itu cukup mengerikan. Tapi itu mungkin saja karena kami telah mencampurkan pengecualian dan kode kesalahan. Kode yang secara konsisten menggunakan kode kesalahan jauh lebih mudah untuk dikerjakan. Jika kode kami secara konsisten menggunakan pengecualian, mungkin itu tidak akan seburuk itu. Mencampur keduanya sepertinya tidak berhasil dengan baik.
sumber
Karena saya bekerja dengan C ++, dan memiliki RAII untuk membuatnya aman digunakan, saya menggunakan pengecualian hampir secara eksklusif. Ini menarik penanganan kesalahan dari aliran program normal dan membuat maksudnya lebih jelas.
Saya meninggalkan pengecualian untuk keadaan luar biasa. Jika saya mengharapkan bahwa kesalahan tertentu akan sering terjadi, saya akan memeriksa bahwa operasi akan berhasil sebelum menjalankannya, atau memanggil versi fungsi yang menggunakan kode kesalahan sebagai gantinya (Suka
TryParse()
)sumber
Tanda tangan metode harus menyampaikan kepada Anda apa yang dilakukan metode tersebut. Sesuatu seperti long errorCode = getErrorCode (); mungkin baik-baik saja, tapi long errorCode = fetchRecord (); membingungkan.
sumber
Pendekatan saya adalah kita dapat menggunakan keduanya, yaitu kode Pengecualian dan Kesalahan pada saat yang bersamaan.
Saya terbiasa mendefinisikan beberapa jenis Pengecualian (mis: DataValidationException atau ProcessInterruptExcepion) dan di dalam setiap pengecualian, tentukan deskripsi yang lebih rinci dari setiap masalah.
Contoh Sederhana di Java:
Dengan cara ini saya menggunakan Pengecualian untuk menentukan kesalahan kategori, dan kode kesalahan untuk menentukan info lebih rinci tentang masalah tersebut.
sumber
throw new DataValidationException("The input is too small")
? Salah satu keuntungan dari pengecualian adalah memungkinkan adanya informasi rinci.Pengecualian adalah untuk keadaan luar biasa - yaitu, saat mereka bukan bagian dari alur normal kode.
Cukup sah untuk mencampur Pengecualian dan kode kesalahan, di mana kode kesalahan mewakili status sesuatu, daripada kesalahan dalam menjalankan kode itu sendiri (misalnya memeriksa kode yang dikembalikan dari proses anak).
Tetapi ketika keadaan luar biasa terjadi, saya yakin Pengecualian adalah model yang paling ekspresif.
Ada kasus di mana Anda mungkin lebih suka, atau harus, menggunakan kode kesalahan sebagai pengganti Pengecualian, dan ini telah dibahas secara memadai (selain kendala lain yang jelas seperti dukungan kompilator).
Namun ke arah lain, menggunakan Pengecualian memungkinkan Anda untuk membangun abstraksi tingkat yang lebih tinggi untuk penanganan kesalahan Anda, yang dapat membuat kode Anda lebih ekspresif dan alami. Saya sangat merekomendasikan membaca artikel yang sangat bagus, namun diremehkan, oleh ahli C ++ Andrei Alexandrescu ini tentang subjek yang dia sebut, "Penegakan": http://www.ddj.com/cpp/184403864 . Meskipun ini adalah artikel C ++ prinsipnya secara umum dapat diterapkan, dan saya telah menerjemahkan konsep penegakan ke C # dengan cukup berhasil.
sumber
Pertama, saya setuju dengan jawaban Tom bahwa untuk barang tingkat tinggi menggunakan pengecualian, dan untuk barang tingkat rendah menggunakan kode kesalahan, selama itu bukan Service Oriented Architecture (SOA).
Dalam SOA, di mana metode dapat dipanggil di mesin yang berbeda, pengecualian tidak boleh melewati kabel, sebagai gantinya, kami menggunakan tanggapan berhasil / gagal dengan struktur seperti di bawah ini (C #):
Dan gunakan seperti ini:
Ketika ini digunakan secara konsisten dalam respons layanan Anda, itu menciptakan pola yang sangat bagus dalam menangani keberhasilan / kegagalan dalam aplikasi. Hal ini memungkinkan penanganan kesalahan yang lebih mudah dalam panggilan asinkron di dalam layanan maupun di seluruh layanan.
sumber
Saya lebih suka Pengecualian untuk semua kasus kesalahan, kecuali jika kegagalan adalah hasil bebas bug yang diharapkan dari fungsi yang mengembalikan tipe data primitif. Misalnya, menemukan indeks substring dalam string yang lebih besar biasanya akan mengembalikan -1 jika tidak ditemukan, alih-alih memunculkan NotFoundException.
Mengembalikan pointer tidak valid yang mungkin direferensikan (misalnya menyebabkan NullPointerException di Java) tidak dapat diterima.
Menggunakan beberapa kode kesalahan numerik yang berbeda (-1, -2) sebagai nilai yang dikembalikan untuk fungsi yang sama biasanya merupakan gaya yang buruk, karena klien mungkin melakukan pemeriksaan "== -1" alih-alih "<0".
Satu hal yang perlu diingat di sini adalah evolusi API dari waktu ke waktu. API yang baik memungkinkan untuk mengubah dan memperluas perilaku kegagalan dalam beberapa cara tanpa merusak klien. Misalnya jika penanganan kesalahan klien memeriksa 4 kasus kesalahan, dan Anda menambahkan nilai kesalahan kelima ke fungsi Anda, penangan klien mungkin tidak menguji ini dan merusak. Jika Anda memunculkan Pengecualian, ini biasanya akan mempermudah klien untuk bermigrasi ke versi perpustakaan yang lebih baru.
Hal lain yang perlu dipertimbangkan adalah saat bekerja dalam tim, di mana harus menarik garis yang jelas bagi semua pengembang untuk membuat keputusan seperti itu. Misalnya "Pengecualian untuk hal-hal tingkat tinggi, kode kesalahan untuk hal-hal tingkat rendah" sangat subjektif.
Dalam kasus apa pun, di mana lebih dari satu jenis kesalahan sepele dimungkinkan, kode sumber tidak boleh menggunakan literal numerik untuk mengembalikan kode kesalahan atau untuk menanganinya (kembalikan -7, jika x == -7 ...), tapi selalu dinamai konstanta (kembalikan NO_SUCH_FOO, jika x == NO_SUCH_FOO).
sumber
Jika Anda bekerja di bawah proyek besar, Anda tidak dapat menggunakan hanya pengecualian atau hanya kode kesalahan. Dalam kasus yang berbeda, Anda harus menggunakan pendekatan yang berbeda.
Misalnya, Anda memutuskan untuk menggunakan pengecualian saja. Tapi begitu Anda memutuskan untuk menggunakan pemrosesan acara async. Ide yang buruk untuk menggunakan pengecualian untuk penanganan kesalahan dalam situasi ini. Tetapi menggunakan kode kesalahan di mana-mana dalam aplikasi itu membosankan.
Jadi pendapat saya bahwa itu normal untuk menggunakan pengecualian dan kode kesalahan secara bersamaan.
sumber
Untuk sebagian besar aplikasi, pengecualian lebih baik. Pengecualiannya adalah ketika perangkat lunak harus berkomunikasi dengan perangkat lain. Domain tempat saya bekerja adalah kontrol industri. Di sini kode kesalahan lebih disukai dan diharapkan. Jadi jawaban saya adalah itu tergantung pada situasinya.
sumber
Saya pikir itu juga tergantung pada apakah Anda benar-benar membutuhkan informasi seperti pelacakan tumpukan dari hasil. Jika ya, Anda pasti memilih Exception yang menyediakan objek yang penuh dengan banyak informasi tentang masalah. Namun, jika Anda hanya tertarik dengan hasil dan tidak peduli mengapa hasil itu, maka gunakan kode kesalahan.
mis. Saat Anda memproses file dan menghadapi IOException, klien mungkin tertarik untuk mengetahui dari mana pemicunya, dalam membuka file atau mem-parsing file, dll. Jadi, lebih baik Anda mengembalikan IOException atau subkelas spesifiknya. Namun, skenario seperti Anda memiliki metode login dan Anda ingin tahu itu berhasil atau tidak, di sana Anda hanya mengembalikan boolean atau untuk menampilkan pesan yang benar, kembalikan kode kesalahan. Di sini Klien tidak tertarik untuk mengetahui bagian logika mana yang menyebabkan kode kesalahan itu. Dia hanya tahu jika Kredensial tidak valid atau kunci akun dll.
Kasus penggunaan lain yang dapat saya pikirkan adalah ketika data berjalan di jaringan. Metode jarak jauh Anda hanya dapat mengembalikan kode kesalahan alih-alih Pengecualian untuk meminimalkan transfer data.
sumber
Aturan umum saya adalah:
sumber
Kode kesalahan juga tidak berfungsi ketika metode Anda mengembalikan apa pun selain nilai numerik ...
sumber