Cara Menerapkan Penanganan Kesalahan [ditutup]

13

Meskipun saya sudah memprogram pada level profesional selama beberapa tahun, saya masih belum sepenuhnya memahami penanganan kesalahan. Meskipun aplikasi saya berfungsi dengan baik, penanganan kesalahan tidak diterapkan pada tingkat profesional dan merupakan campuran dan kecocokan dari sejumlah teknik.

Tidak ada struktur di belakang penanganan kesalahan saya. Saya ingin belajar dan memahami bagaimana penerapannya di tingkat profesional. Ini adalah satu area di mana saya kurang pengetahuan.

Kapan saya harus menggunakan pengecualian dan kapan saya harus mengembalikan status keberhasilan, untuk diperiksa dalam aliran logika? Apakah boleh mencampur pengecualian dan mengembalikan status?

Saya kode dalam C # terutama.

James Jeffery
sumber
2
Mengapa memilih? Saya mengajukan pertanyaan serius tentang implementasi penanganan kesalahan dan bagaimana melakukannya. Jika ini bukan tempat terbaik untuk mengajukan pertanyaan seperti itu di antara programmer, lalu di mana? Benar-benar menggangguku ketika orang-orang memilih pertanyaan seperti itu karena tidak ada tempat lain untuk menanyakan pertanyaan seperti itu. Mungkin satu-satunya tempat di web di mana saya akan mendapatkan jawaban yang andal dan sumber daya yang mungkin. Jadi, alih-alih menjawab pertanyaan, orang lain pasti akan memilih Google, bukankah lebih mudah untuk menjawabnya?
James Jeffery
6
Pertanyaan Anda sangat luas. Mungkin Anda bisa mempersempit ruang lingkup dengan menghubungkan contoh spesifik tentang bagaimana Anda gagal mencapai tujuan pengkodean Anda.
Andyz Smith
Ada banyak artikel di web tentang penanganan kesalahan: Coba ini: msdn.microsoft.com/en-us/library/seyhszts.aspx
Nir Kornfeld

Jawaban:

25
  1. Gunakan pengecualian untuk hal-hal luar biasa, hal-hal yang tidak dapat Anda harapkan terlalu sering terjadi, hal-hal yang mengindikasikan bahwa ada yang tidak beres. Misalnya, jika jaringan mati, itu adalah hal yang luar biasa untuk server web. Jika database tidak tersedia, itu berarti ada sesuatu yang salah. Jika file konfigurasi tidak ada, itu mungkin berarti pengguna mengacaukannya.

  2. Jangan gunakan pengecualian untuk menangani kode yang salah. Untuk memeriksa kebenaran kode, Anda harus menggunakan asersi, atau, dalam .NET Framework 4 dan yang lebih baru, kontrak Kode (yang menggantikan asersi dan memiliki fitur tambahan, terutama yang berharga).

  3. Jangan gunakan pengecualian dalam kasus yang tidak biasa. Fakta bahwa pengguna, ketika diminta untuk memasukkan nomor, memasukkan "anjing" tidak begitu luar biasa untuk mendapatkan pengecualian.

  4. Hati-hati saat memilih jenis pengecualian. Buat jenis Anda sendiri saat dibutuhkan. Hati-hati memilih warisan, dengan mengingat bahwa menangkap orang tua juga akan menangkap anak-anak. Tidak pernah throw Exception.

  5. Jangan gunakan kode pengembalian untuk kesalahan. Kode kesalahan mudah ditutup, diabaikan, dilupakan. Jika ada kesalahan, peganglah, atau sebarkan ke tumpukan atas.

  6. Dalam kasus di mana suatu metode diharapkan untuk mengembalikan kesalahan dan kesalahan itu tidak luar biasa, gunakan enums, jangan pernah nomor kesalahan. Contoh:

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }

    Arti dari LoadOperationResult.ServerUnavailable,, LoadOperationResult.ParsingErrordll. Jauh lebih eksplisit daripada, katakanlah, mengingat bahwa kode 12 berarti bahwa server sedang down, dan kode 13 - bahwa data tidak dapat diuraikan.

  7. Gunakan kode kesalahan saat merujuk pada yang umum, yang diketahui oleh setiap pengembang yang bekerja di domain tertentu. Misalnya, jangan menemukan kembali nilai enum untuk HTTP 404 Not Found atau HTTP 500 Internal Server Error.

  8. Waspadalah terhadap booleans. Cepat atau lambat, Anda akan ingin tahu tidak hanya apakah metode tertentu berhasil atau gagal, tetapi mengapa. Pengecualian dan enum jauh lebih kuat untuk itu.

  9. Jangan menangkap setiap pengecualian (kecuali Anda berada di bagian paling atas tumpukan). Jika Anda menangkap pengecualian, Anda harus siap menanganinya. Menangkap semuanya menunjukkan bahwa Anda tidak peduli jika kode Anda berjalan dengan benar. Ini mungkin memecahkan "Saya tidak ingin mencari sekarang bagaimana cara memperbaikinya", tetapi akan menyakiti Anda cepat atau lambat.

  10. Dalam C #, jangan pernah ubah kembali pengecualian seperti ini:

    catch (SomeException ex)
    {
        ...
        throw ex;
    }

    karena Anda melanggar tumpukan. Lakukan ini sebagai gantinya:

    catch (SomeException)
    {
        ...
        throw;
    }
  11. Usahakan saat menulis pesan pengecualian. Berapa kali saya melihat sesuatu seperti throw Exception("wrong data")atau throw Exception("shouldn't call this method in this context"). Pengembang lain, termasuk Anda sendiri enam bulan kemudian, tidak akan tahu data apa yang salah dan mengapa atau mengapa kita tidak memanggil beberapa metode dalam suatu konteks, atau konteks mana yang tepat.

  12. Jangan tampilkan pesan pengecualian kepada pengguna. Mereka tidak diharapkan untuk orang-orang biasa, dan sering bahkan tidak dapat dibaca untuk pengembang sendiri.

  13. Jangan melokalkan pesan pengecualian. Mencari dokumentasi untuk pesan lokal sangat melelahkan dan tidak ada gunanya: setiap pesan harus hanya dalam Bahasa Inggris dan Bahasa Inggris.

  14. Jangan fokus secara eksklusif pada pengecualian dan kesalahan: log juga sangat penting.

  15. Dalam .NET, jangan lupa untuk memasukkan pengecualian dalam dokumentasi XML metode ini:

    /// <exception cref="MyException">Description of the exception</exception>

    Menyertakan pengecualian dalam dokumentasi XML membuat segalanya lebih mudah bagi orang yang menggunakan perpustakaan. Tidak ada yang lebih menyebalkan daripada mencoba menebak pengecualian mana yang bisa dilemparkan dengan metode dan alasannya.

    Dalam hal ini¹, penanganan pengecualian Java menyediakan pendekatan yang lebih ketat dan lebih baik. Ini memaksa Anda untuk berurusan dengan pengecualian yang berpotensi dilemparkan oleh metode yang disebut, atau menyatakan dengan metode Anda sendiri bahwa itu dapat membuang pengecualian yang tidak Anda tangani, membuat hal-hal menjadi sangat transparan.


¹ Dikatakan demikian, saya menemukan perbedaan antara pengecualian dan kesalahan di Jawa tidak berguna dan membingungkan, mengingat bahasanya telah memeriksa dan menghapus pengecualian. Untungnya, .NET Framework hanya memiliki pengecualian, dan tidak ada kesalahan.

MainMa
sumber
Saya belajar sedikit mengutip dari ini, Bolehkah saya bertanya dari mana daftar itu berasal? Situs atau pengalaman pribadi? Either way pekerjaan yang luar biasa (hehe mengerti?).
Shelby115
@ Shelby115: daftar berasal dari, dalam urutan: Stack Exchange, pengalaman pribadi dan Kode Lengkap oleh Steve Mcconnell.
Arseni Mourzenko
Terima kasih @MainMa, itu respons yang luar biasa! Saya dulu memiliki Kode Lengkap ketika saya di Universitas tetapi seseorang mencurinya. Saya tidak bisa membacanya.
James Jeffery
@JamesJeffery: lalu pinjam edisi kedua di perpustakaan, atau beli satu: itu adalah salah satu buku terkait pengembangan langka yang benar-benar bernilai uang.
Arseni Mourzenko
@MainMa Baru saja memesan dari Amazon, terima kasih: DI juga memiliki Kode Bersih, dan benar-benar lupa tentang Bab 7.
James Jeffery
1

Saya pikir daftar MainMa sangat lengkap. Saya hanya akan menambahkan beberapa milik saya sendiri:

  1. Baca artikel Eric Lippert tentang bagaimana dia mengelompokkan pengecualian. Yang sangat penting adalah pendapatnya tentang tidak menangkap pengecualian yang pada kenyataannya bug dalam kode Anda. Perbaiki kodenya!
  2. Jika Anda tahu bahwa pengecualian dapat terjadi DAN Anda dapat melakukan sesuatu tentang itu, tangani itu, tetapi batasi ruang lingkup Anda mencoba-menangkap dan menangkap pengecualian spesifik yang Anda harapkan. Yaitu, jangan lakukan ini:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

Alih-alih lakukan ini:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • Jangan gunakan pengecualian untuk aliran kontrol. Misalnya, jangan melempar ClientNotFoundException dalam dialog pencarian (klien yang tidak ditemukan tidak biasa dalam situasi ini) dan mengharapkan kode panggilan untuk menampilkan pesan "Tidak ditemukan hasil" ketika ini terjadi.

  • Jangan menelan pengecualian!

  • Perlu diingat bahwa benar-benar menangani pengecualian hanya dapat berarti 3 hal:

    1. Coba lagi operasi. Hanya valid jika masalahnya sementara.
    2. Coba alternatif lain.
    3. Beri tahu seseorang tentang masalahnya. Hanya valid jika pemberitahuan dapat ditindaklanjuti, artinya pengguna dapat melakukan sesuatu tentangnya.

    Jika tidak ada opsi ini yang berlaku maka Anda mungkin tidak harus menangkap pengecualian itu. Anda harus mencatatnya, kemudian membatalkan operasi atau mematikannya. Tentu saja ini tergantung apa persyaratan Anda dalam hal ketepatan vs ketangguhan.

Mike
sumber