Pesan-pesan itu untuk pengembang lain
Pesan-pesan itu diharapkan dibaca oleh pengembang untuk membantu mereka men-debug aplikasi. Ini dapat mengambil dua bentuk:
Debugging aktif. Anda sebenarnya menjalankan debugger saat menulis kode dan mencoba mencari tahu apa yang terjadi. Dalam konteks ini, pengecualian yang bermanfaat akan memandu Anda dengan membuatnya mudah untuk memahami apa yang salah, atau akhirnya menyarankan solusi (meskipun ini opsional).
Debugging pasif. Kode berjalan dalam produksi dan gagal. Pengecualian dicatat, tetapi Anda hanya mendapatkan pesan dan jejak tumpukan. Dalam konteks ini, pesan pengecualian yang membantu akan membantu Anda dengan cepat melokalisasi bug.
Karena pesan-pesan itu sering dicatat, itu juga berarti Anda tidak boleh memasukkan informasi sensitif di sana (seperti kunci pribadi atau kata sandi, bahkan jika itu bisa berguna untuk men-debug aplikasi).
Misalnya, IOSecurityException
jenis pengecualian yang dilemparkan saat menulis file tidak terlalu eksplisit tentang masalahnya: apakah karena kita tidak memiliki izin untuk mengakses file? Atau mungkin kita bisa membacanya, tetapi tidak menulis? Atau mungkin file itu tidak ada dan kami tidak memiliki izin untuk membuat file di sana? Atau mungkin terkunci (mudah-mudahan, jenis pengecualian akan berbeda dalam kasus ini, tetapi dalam praktiknya, jenis kadang-kadang bisa samar). Atau mungkin Keamanan Akses Kode mencegah kita dari melakukan operasi I / O?
Sebagai gantinya:
IOSecurityException: file ditemukan tetapi izin untuk membaca isinya ditolak.
jauh lebih eksplisit. Di sini, kita segera tahu bahwa izin pada direktori diatur dengan benar (jika tidak, kita tidak akan dapat mengetahui bahwa file itu ada), tetapi izin di tingkat file bermasalah.
Ini juga berarti bahwa jika Anda tidak dapat memberikan informasi tambahan yang belum termasuk dalam jenis pengecualian, Anda dapat menyimpan pesan tersebut kosong. DivisionByZeroException
adalah contoh yang bagus di mana pesannya berlebihan. Di sisi lain, kenyataan bahwa sebagian besar bahasa membiarkan Anda mengeluarkan pengecualian tanpa menentukan pesannya dilakukan karena alasan yang berbeda: baik karena pesan default sudah tersedia, atau karena akan dihasilkan nanti jika diperlukan (dan generasi ini pesan terlampir di dalam tipe pengecualian, yang masuk akal, "OOPly" berbicara).
Perhatikan bahwa karena alasan teknis (seringkali kinerja), beberapa pesan pada akhirnya menjadi jauh lebih samar dari seharusnya. .NET's NullReferenceException
:
Referensi objek tidak disetel ke instance objek.
adalah contoh luar biasa dari pesan yang tidak membantu. Pesan yang bermanfaat adalah:
Referensi objek product
tidak disetel ke instance objek ketika dipanggil product.Price
.
Pesan-pesan itu bukan untuk pengguna akhir!
Pengguna akhir tidak diharapkan melihat pesan pengecualian. Tak pernah. Meskipun beberapa pengembang akhirnya menunjukkan pesan-pesan itu kepada pengguna, ini mengarah pada pengalaman dan frustrasi pengguna yang buruk. Pesan seperti:
Referensi objek tidak disetel ke instance objek.
sama sekali tidak berarti bagi pengguna akhir, dan harus dihindari dengan cara apa pun.
Skenario kasus terburuk adalah mencoba global / menangkap yang melempar pengecualian kepada pengguna dan keluar dari aplikasi. Aplikasi yang peduli dengan penggunanya:
Menangani pengecualian di tempat pertama. Sebagian besar dapat ditangani tanpa mengganggu pengguna. Jaringan mati? Mengapa tidak menunggu beberapa detik dan coba lagi?
Mencegah pengguna dari mengarahkan aplikasi ke kasus luar biasa. Jika Anda meminta pengguna untuk memasukkan dua angka dan membagi yang pertama dengan yang kedua, mengapa Anda membiarkan pengguna untuk memasukkan nol dalam kasus kedua untuk menyalahkannya beberapa detik kemudian? Bagaimana dengan menyorot kotak teks berwarna merah (dengan tip alat yang membantu mengatakan bahwa angka harus berbeda dari nol) dan menonaktifkan tombol validasi hingga bidang tetap merah?
Mengundang pengguna untuk melakukan tindakan dalam formulir yang bukan merupakan kesalahan. Tidak ada izin yang cukup untuk mengakses file? Mengapa tidak meminta pengguna untuk memberikan izin administratif, atau memilih file yang berbeda?
Jika tidak ada yang berfungsi, menunjukkan kesalahan, ramah kesalahan yang secara khusus ditulis untuk mengurangi frustrasi pengguna, membantu pengguna untuk memahami apa yang salah dan akhirnya menyelesaikan masalah, dan juga membantunya mencegah kesalahan di masa depan (bila berlaku).
Dalam pertanyaan Anda, Anda menyarankan untuk memiliki dua pesan sebagai pengecualian: satu pesan teknis untuk pengembang, dan satu pesan untuk pengguna akhir. Meskipun ini adalah saran yang valid dalam beberapa kasus kecil, sebagian besar pengecualian diproduksi pada tingkat di mana tidak mungkin untuk menghasilkan pesan yang bermakna bagi pengguna. Ambil DivisionByZeroException
dan bayangkan bahwa kita tidak dapat mencegah pengecualian terjadi dan tidak bisa mengatasinya sendiri. Ketika pembagian terjadi, apakah kerangka kerja (karena kerangka kerja, dan bukan kode bisnis, yang melempar pengecualian) tahu apa yang akan menjadi pesan yang bermanfaat bagi pengguna? Benar-benar tidak:
Pembagian dengan nol terjadi. [BAIK]
Sebagai gantinya, seseorang dapat membiarkannya membuang pengecualian, dan kemudian menangkapnya di tingkat yang lebih tinggi di mana kami mengetahui konteks bisnis dan dapat bertindak sesuai untuk benar-benar membantu pengguna akhir, sehingga menunjukkan sesuatu seperti:
Bidang D13 tidak dapat memiliki nilai yang identik dengan yang ada di bidang E6, karena pengurangan nilai-nilai tersebut digunakan sebagai pembagi. [BAIK]
atau mungkin:
Nilai yang dilaporkan oleh layanan ATP tidak konsisten dengan data lokal. Ini mungkin disebabkan oleh data lokal yang tidak sinkron. Apakah Anda ingin menyinkronkan informasi pengiriman dan coba lagi? [Ya Tidak]
Pesan-pesan itu bukan untuk diuraikan
Pesan pengecualian juga tidak diharapkan untuk diuraikan atau digunakan secara terprogram. Jika Anda berpikir bahwa informasi tambahan dapat dibutuhkan oleh penelepon, sertakan dalam perkecualian berdampingan dengan pesan. Ini penting, karena pesan dapat berubah tanpa pemberitahuan. Ketik adalah bagian dari antarmuka, tetapi pesannya tidak: jangan pernah bergantung padanya untuk penanganan pengecualian.
Bayangkan pesan pengecualian:
Menghubungkan ke caching memutuskan batas waktu setelah menunggu 500 ms. Tingkatkan batas waktu atau periksa pemantauan kinerja untuk mengidentifikasi penurunan kinerja server. Waktu tunggu rata-rata untuk server caching adalah 6 ms. selama sebulan terakhir, 4 ms. selama seminggu terakhir dan 377 ms. selama satu jam terakhir.
Anda ingin mengekstraksi nilai "500", "6", "4" dan "377". Pikirkan sedikit tentang pendekatan yang akan Anda gunakan untuk melakukan parsing, dan baru kemudian melanjutkan membaca.
Anda punya ide? Besar.
Sekarang, pengembang asli menemukan kesalahan ketik:
Connecting to the caching sever timed out after waiting [...]
seharusnya:
↓
Connecting to the caching server timed out after waiting [...]
Selain itu, pengembang menganggap bahwa bulan / minggu / satu jam tidak terlalu relevan, jadi ia juga melakukan perubahan tambahan:
Waktu tunggu rata-rata untuk server caching adalah 6 ms. selama sebulan terakhir, 5 ms. selama 24 jam terakhir dan 377 ms. selama satu jam terakhir.
Apa yang terjadi dengan parsing Anda?
Alih-alih mem-parsing, Anda bisa menggunakan properti pengecualian (yang dapat berisi apa pun yang diinginkan seseorang, segera setelah data dapat diserialisasi):
{
message: "Connecting to the caching [...]",
properties: {
"timeout": 500,
"statistics": [
{ "timespan": 1, "unit": "month", "average-timeout": 6 },
{ "timespan": 7, "unit": "day", "average-timeout": 4 },
{ "timespan": 1, "unit": "hour", "average-timeout": 377 },
]
}
}
Seberapa mudah menggunakan data ini sekarang?
Kadang-kadang (seperti dalam .NET), pesan tersebut bahkan dapat diterjemahkan ke dalam bahasa pengguna (IMHO, menerjemahkan pesan-pesan itu benar-benar salah, karena setiap pengembang diharapkan dapat membaca dalam bahasa Inggris). Mem-parsing pesan semacam itu hampir mustahil.