Haruskah lapisan layanan menangkap semua pengecualian dao dan membungkusnya sebagai pengecualian layanan?

23

Saya memiliki tiga aplikasi web Spring layer: dao, layanan, dan pengontrol. Kontroler tidak pernah memanggil langsung dao, ia melakukannya melalui lapisan layanan. Saat ini, sebagian besar waktu jika ada pengecualian dao (runtime) yang tidak ditangani, itu akan ditangkap oleh JSP yang menunjukkan pesan kesalahan kepada pengguna akhir. Haruskah lapisan layanan menangkap semua pengecualian dao dan membungkusnya sebagai pengecualian layanan?

try {
   daoInstance.someDaoMethod();
} catch(DataAccessException dae) {
   throw new ServiceException("message", dae);
}

Mari kita anggap ServiceException juga runtime dan tidak ditangani juga. Apakah ada perbedaan untuk hanya membuang DataAccessException daripada ServiceException? Saya hanya berpikir bahwa lapisan presentasi tidak boleh tahu tentang pengecualian akses data. Tapi saya tidak melihat titik menangkap pengecualian yang tidak dapat dipulihkan hanya untuk membungkusnya.

Oscar
sumber

Jawaban:

18

Saya pikir faktor penting adalah siapa klien layanan Anda.

Jika lapisan layanan Anda hanyalah batas arsitektural antara lapisan dalam proyek Anda sendiri, dan klien layanan berada dalam bidang kepercayaan yang sama, maka ok saja untuk bersantai, dan biarkan pengecualian yang tidak dicentang muncul ke lapisan pengontrol, atau klien layanan.

Namun, untuk kode yang dihadapi publik; layanan yang dikonsumsi oleh pihak ketiga atau pelanggan, saya pikir lebih baik untuk membungkus pengecualian yang tidak dicentang dengan pengecualian berorientasi layanan, terutama untuk masalah keamanan, kedua untuk kopling longgar, dan abstraksi bersih.

Pengecualian lapisan data tidak boleh, secara langsung membuatnya sampai ke pengguna akhir dari aplikasi web . Ini berpotensi berisi informasi internal tentang skema Anda, pertanyaan Anda, informasi nomor baris, nama variabel atau fungsi, dll. Pengecualian pengguna akhir dapat disanitasi dalam pengaturan yang aman.

Klien layanan eksternal tidak mementingkan detail implementasi Anda, dan toh tidak dapat menangani pengecualian yang tidak dicentang, karena mereka adalah bug atau masalah lingkungan. Dalam aplikasi yang aman, kesalahan database tidak cukup aman untuk disebarkan, OracleException - ORA-01234 - ...yang mungkin merupakan tabel ke-3 yang dimasukkan. Klien harus diizinkan untuk berurusan dengan pengecualian yang dicek / diharapkan yang dapat ditangani, dan memperlakukan yang lainnya sebagai laporan bug yang potensial. Kontrak layanan Anda harus berupa abstraksi atom, konsisten, transaksional. Jika tidak dapat melakukan apa-apa tentang pengecualian, maka satu-satunya hal berguna yang tersisa adalah memberi Anda laporan bug. Anda sudah memiliki kemampuan untuk mencatat pengecualian, jadi mengapa membebani pengguna akhir Anda dengan detailnya? Aplikasi Anda dapat dipantau sehingga Anda sudah tahu tentang pengecualian yang tidak dicentang sebelum pengguna melaporkannya.

Tidak pernah ok untuk makan pengecualian, saya juga bukan penggemar pengecualian yang diperiksa, tetapi saya lebih suka memiliki rencana yang sesuai untuk sifat keseluruhan produk.

codenheim
sumber
13

Tidak, Anda tidak boleh membungkus pengecualian DAO dalam aplikasi web

Ada banyak suara dalam kode tanpa manfaat. Pengecualian DAO adalah pengecualian yang tidak dicentang karena alasan yang baik. Kode aplikasi tidak dapat melakukan apa pun yang berguna untuk memulihkan dari pengecualian DAO. Masalah sebenarnya ada di sini:

... itu akan ditangkap oleh JSP yang menunjukkan pesan kesalahan kepada pengguna akhir.

Perbaiki masalah ini di satu tempat alih-alih mengacaukan seluruh basis kode.

Anda mengontrol bagaimana pengecualian tanpa tertangkap ditampilkan kepada pengguna. Pengecualian tanpa tertangkap disebabkan oleh bug aplikasi atau kegagalan dalam sistem yang mendasarinya. Tidak ada alasan untuk memberikan informasi apa pun kepada pengguna tentang alasan permintaannya tidak dapat dilayani. Tidak ada yang bisa dilakukan pengguna. Yang harus Anda lakukan adalah melayani halaman kesalahan yang ramah.

NB: jika Anda menemukan diri Anda sedang menulis banyak kode yang membosankan, misalnya, membuat banyak blok tangkap yang hanya membungkus dan melempar ulang, hampir selalu ada solusi yang lebih baik.

kevin cline
sumber
Terima kasih atas jawaban anda. Dan ya, jsp menunjukkan pesan khusus: "Ups, ada yang salah". Itu tidak menunjukkan informasi tentang pengecualian
Oscar
7

Alasan utama seseorang akan menggunakan pembungkus pengecualian adalah untuk mencegah kode di lapisan bisnis dari harus tahu tentang setiap pengecualian yang mungkin dalam sistem . Ada dua alasan utama untuk ini:

  • Konsistensi: pernyataan pengecualian agregat menuju bagian atas tumpukan panggilan. Jika Anda tidak membungkus pengecualian, tetapi meneruskannya dengan mendeklarasikan metode Anda untuk membuangnya, Anda mungkin berakhir dengan metode tingkat atas yang menyatakan banyak pengecualian berbeda. Mendeklarasikan semua pengecualian ini dalam setiap metode yang membuat cadangan tumpukan panggilan menjadi membosankan.

  • Enkapsulasi: Anda mungkin tidak ingin komponen tingkat atas Anda tahu apa-apa tentang komponen tingkat bawah, atau pengecualian yang mereka berikan. Sebagai contoh, tujuan dari antarmuka dan implementasi DAO adalah untuk mengabstraksi perincian akses data dari aplikasi lainnya. Sekarang, jika metode DAO Anda melempar SQLException maka kode menggunakan DAO harus menangkap mereka. Bagaimana jika Anda mengubah ke implementasi yang membaca data dari layanan web, bukan dari database? Maka Anda metode DAO harus membuang RemoteException dan SQLException. Dan, jika Anda memiliki DAO yang membaca data dari file, Anda juga perlu membuang IOException. Itu adalah tiga pengecualian yang berbeda, masing-masing terikat pada implementasi DAO mereka sendiri.

Jadi, singkatnya, jawabannya adalah ya!

fabienbk
sumber
3
Implementasi JPA (misalnya Hibernate) membuang pengecualian yang tidak dicentang. Mereka tidak harus dinyatakan atau ditangkap.
kevin cline