Est-ce toujours un contre-modèle si nous enregistrons un message d'exception et levons une exception différente?

18

Notre webapplication utilise un ExceptionMapperà la carte des exceptions à Response. Nous enregistrons les messages d'exception avant de lancer une nouvelle exception les suivants:

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

Nous ne repoussons pas la même exception , donc ma question est de savoir si cela serait considéré comme un contre -modèle Log and Throw . Et ainsi, serait - il préférable d'enlever l'exploitation forestière dans des endroits semblables et les déplacer à plusieurs ExceptionMapperclasses:

@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
la source
3
Je vous arrêterais dès que vous vous connecteriez ex.getMessage(), c'est déjà faux.
biziclop
OMI, il n'est pas vraiment juste de ne pas mentionner du tout qu'il s'agit d'un service Web. Cela change vraiment les règles du jeu, car par exemple, le simple fait d'utiliser des mécanismes de gestion des exceptions ordinaires peut constituer un risque pour la sécurité; vous ne voulez pas que toute exception soit renvoyée dans une réponse d'erreur 500, qui doit être vérifiée et filtrée. La journalisation agressive sur place est également beaucoup plus courante lorsque vous traitez avec des systèmes qui ont des clients externes qui l'invoquent directement. La journalisation des traces de pile dans les appels de service qui sont invoquées à plusieurs reprises peut entraîner des tailles de fichier journal ingérables et des problèmes de performances.
@Gimby Dans ce cas , OP ne transmet aucun détail d'erreur dans la réponse (peut - être un boilerplate « erreur » contenu). De plus, comment diagnostiquez-vous un problème sans trace de pile? Les enregistreurs à rouleaux prennent régulièrement en charge la taille du stockage et les données des journaux sont compressibles de manière embarrassante.
Marko Topolnik

Réponses:

36

Votre code ne comporte en fait pas un, mais trois contre- modèles:

  1. se connecter et retomber;
  2. renvoyer sans envelopper la cause d'origine;
  3. consigner uniquement le message et non la trace de pile (c'est le pire).

Si vous avez suivi la meilleure pratique pour:

  1. ne pas attraper du tout (laissez l'exception se propager d'elle-même);
  2. s'il est forcé d'attraper une exception vérifiée, encapsulez-la sans contrôle et relancez;
  3. ne connectez jamais rien sauf au niveau supérieur;
  4. consigner l'intégralité de la trace des exceptions avec log.error("Error occurred", e);

vous ne rencontriez alors aucun dilemme, y compris le vôtre, car la trace de pile consignée inclurait également toutes les exceptions encapsulées.

Marko Topolnik
la source