Apakah ini masih antipengganti jika kita mencatat pesan pengecualian dan melemparkan pengecualian yang berbeda?

18

Aplikasi web kami menggunakan a ExceptionMapperuntuk memetakan beberapa pengecualian Response. Kami mencatat pesan pengecualian sebelum melemparkan pengecualian baru sebagai berikut:

catch (SomeException ex) {
  LOG.error(ex.getMessage());
  throw new MyException(ex.getMessage());
}

Kami tidak melempar kembali pengecualian yang sama , jadi pertanyaan saya adalah apakah ini akan dianggap sebagai antipattern Log dan Throw . Dan dengan demikian, akan lebih baik untuk menghapus logging di tempat yang sama dan memindahkannya ke beberapa ExceptionMapperkelas sebagai berikut:

@Provider
public class MyExceptionMapper implements ExceptionMapper<MyException> {

  // bla bla 

  @Override
  public Response toResponse(final MyException ex) {
    LOG.error(ex.getMessage());
    return Response.status(400).entity("something").build();
  }
}
Diyarbakir
sumber
3
Saya akan menghentikan Anda begitu Anda login ex.getMessage(), itu sudah salah.
biziclop
IMO itu tidak benar-benar adil untuk tidak menyebutkan sama sekali bahwa ini adalah layanan web. Itu benar-benar mengubah aturan permainan, karena misalnya hanya menggunakan mekanisme penanganan pengecualian biasa bisa menjadi risiko keamanan; Anda tidak ingin ada dan semua pengecualian hanya dikirim kembali dalam respons 500 kesalahan, yang perlu diperiksa dan difilter. Penebangan di tempat yang agresif juga jauh lebih umum ketika berhadapan dengan sistem yang memiliki klien eksternal yang memintanya secara langsung. Logout stacktraces dalam panggilan layanan yang dipanggil berulang kali dapat menyebabkan ukuran file log yang tidak terkelola dan masalah kinerja.
@ Gimby Dalam hal ini OP tidak mengirim detail kesalahan apa pun dalam respons (mungkin konten "kesalahan terjadi" pada boilerplate). Juga, bagaimana Anda mendiagnosis masalah tanpa stacktrace? Rolling logger secara rutin menjaga ukuran penyimpanan dan data log secara kompresif.
Marko Topolnik

Jawaban:

36

Kode Anda sebenarnya bukan hanya satu, tetapi tiga antipattern:

  1. log dan rethrow;
  2. rethrow tanpa membungkus penyebab aslinya;
  3. hanya log pesan dan bukan stacktrace (ini adalah yang terburuk).

Jika Anda mengikuti praktik terbaik untuk:

  1. tidak menangkap sama sekali (biarkan pengecualian menyebar sendiri);
  2. jika dipaksa untuk menangkap pengecualian yang dicek, bungkus menjadi tidak dicentang dan rethrow;
  3. tidak pernah mencatat apa pun kecuali di tingkat atas;
  4. catat seluruh pengecualian stacktrace dengan log.error("Error occurred", e);

maka Anda tidak akan menghadapi dilema apa pun, termasuk yang Anda alami saat ini, karena stacktrace yang dicatat akan menyertakan semua pengecualian yang dibungkus juga.

Marko Topolnik
sumber