web-dev-qa-db-fra.com

Pourquoi le «log and throw» est-il considéré comme un anti-modèle?

Cette question a été déclenchée par une discussion autour de cet article , où je n'ai pas reçu de bonnes réponses.

Pourquoi la consignation de votre exception puis sa relance (en conservant la trace de la pile d'origine bien sûr) serait-elle une mauvaise idée si vous ne pouvez pas la gérer autrement?

70
Manu

Je suppose que la réponse est en grande partie parce que pourquoi l'attrapez-vous si vous ne pouvez pas le gérer? Pourquoi ne pas laisser celui qui peut le gérer (ou celui qui n'a d'autre choix que de le gérer) l'enregistrer, s'il estime qu'il est digne d'un journal?

Si vous l'attrapez, le connectez et le relancez, il n'y a aucun moyen pour le code en amont de savoir que vous avez déjà enregistré l'exception, et donc la même exception peut être enregistrée deux fois. Ou pire, si tout le code en amont suit ce même modèle, l'exception peut être enregistrée un nombre arbitraire de fois, une fois pour chaque niveau du code qui décide de l'attraper, de le journaliser, puis de le renvoyer.

Certains pourraient également affirmer que puisque les exceptions de lancement et de capture sont des opérations relativement coûteuses, toutes ces opérations de capture et de réexécution n'aident pas vos performances d'exécution. Cela n'aide pas non plus votre code en termes de concision ou de maintenabilité.

94
aroth

Le log-and-throw est un bon modèle si l'entité qui capture et rejette l'exception a des raisons de croire qu'elle contient des informations qui ne seront pas enregistrées plus loin dans la pile des appels - du moins pas de la manière la plus souhaitée. Cela peut se produire pour plusieurs raisons:

  1. L'exception peut être interceptée et renvoyée à une limite de couche application et peut contenir des informations privilégiées. Il serait mauvais pour une couche de base de données d'autoriser une exception disant, par exemple "Tenter d'ajouter la clé en double 'fnord' au champ 'utilisateurs'" pour atteindre la couche d'application externe (qui pourrait à son tour l'exposer à un utilisateur), mais il pourrait être utile pour les parties internes de la base de données de lever une telle exception et l'interface d'application pour l'attraper, l'enregistrer en toute sécurité et renvoyer une exception un peu moins descriptive.
  2. L'exception peut être une que la couche externe s'attendrait probablement à gérer sans journalisation, mais la couche interne peut savoir quelque chose que la couche externe ne sait pas, ce qui suggère que la journalisation peut être utile. À titre d'exemple grossier, une couche d'application intermédiaire peut être programmée pour essayer de se connecter à un serveur et, si cela ne fonctionne pas, essayez un autre. Inonder le journal de l'application avec des messages `` échec de connexion '' alors qu'un serveur est en panne pour maintenance peut ne pas être utile, d'autant plus que - du point de vue de l'application, tout a bien fonctionné. Il peut être utile de transmettre des informations sur l'échec de la connexion à une ressource de journalisation associée aux serveurs, qui pourrait ensuite filtrer les journaux afin de produire un rapport indiquant quand le serveur est monté et descendu, par opposition à un journal de chaque tentative de connexion. .
43
supercat

Je suppose que la raison la plus simple est que vous auriez généralement un seul gestionnaire de haut niveau qui le ferait pour vous, il n'est donc pas nécessaire de polluer le code avec cette gestion des exceptions.

L'argument des préoccupations transversales est essentiellement que c'est une perte de temps de gérer les erreurs qui ne vous concernent pas. Il vaut mieux laisser l'erreur remonter la pile d'appels jusqu'à ce qu'un gestionnaire approprié soit trouvé.

À mon avis, le seul moment où vous devriez attraper une exception est lorsque vous pouvez faire quelque chose d'utile avec les résultats. Attraper simplement pour vous connecter n'est pas utile, car vous pouvez centraliser ce travail plus loin.

16
Jeff Foster

Le journal et le lancer de l'OMI constituent une violation flagrante du principe de la moindre surprise.

Si l'exception est gérée correctement plus haut dans la pile des appels, cela ne vaut peut-être pas du tout une entrée de journal des erreurs. Et puis, il est difficile de trouver une entrée dans le journal des erreurs.

7
Bastian Voigt