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

Cette question a été suscitée par une discussion autour de cet article , où je n’ai reçu aucune bonne réponse.

Pourquoi la journalisation de votre exception et sa relecture (en conservant bien sûr la trace de la stack d’origine) serait-elle une mauvaise idée si vous ne pouvez pas le gérer autrement?

Je suppose que la réponse est en grande partie parce que pourquoi attrapez-vous si vous ne pouvez pas le gérer? Pourquoi ne pas laisser quiconque peut le gérer (ou quiconque n’a pas d’autre choix que de le gérer) le connecte, s’il a le sentiment que c’est digne d’être connecté?

Si vous le capturez et que vous le connectez et le relancez, le code en amont n’a aucun moyen de savoir que vous avez déjà consigné l’exception et que la même exception peut être consignée deux fois. Ou pire, si tout le code en amont suit ce même modèle, l’exception peut être consignée un nombre de fois arbitraire, une fois pour chaque niveau du code qui décide de l’attraper, le connecter et le relancer.

Certains diront peut-être également que, étant donné que lancer et intercepter des exceptions sont des opérations relativement coûteuses, toutes ces opérations de rattrapage et de redirection ne consortingbuent pas aux performances de votre environnement d’exécution. Cela ne consortingbue pas non plus à votre code en termes de concision ou de maintenabilité.

Log-and-throw est un bon modèle si l’entité intercepte et redirige l’exception a des raisons de croire qu’elle contient des informations qui ne seront pas consignées plus haut dans la stack des appels – du moins pas de la manière la plus désirée. Quelques raisons peuvent expliquer ceci:

  1. L’exception peut être interceptée et retransmise à une limite de couche d’application et peut contenir des informations privilégiées. Il serait mauvais pour une couche de firebase database d’autoriser une exception, par exemple “Tentative d’append la clé dupliquée ‘fnord’ au champ ‘users'” pour atteindre la couche d’application externe (qui pourrait à son tour l’exposer à un utilisateur). pourrait être utile pour les parties internes de la firebase database pour lancer une telle exception et l’interface de l’application pour l’attraper, la connecter en toute sécurité et relancer une exception un peu moins descriptive.
  2. L’exception pourrait être une couche que la couche externe s’attendrait à manipuler sans se connecter, mais la couche interne peut savoir quelque chose que la couche externe ne reconnaît pas, ce qui suggère que la journalisation peut être utile. À titre d’exemple, une couche d’application intermédiaire peut être programmée pour essayer de se connecter à un serveur et, si cela ne fonctionne pas, essayez-en une autre. Inverser le journal de l’application avec des messages «Échec de la connexion» lorsqu’un serveur est arrêté pour maintenance peut ne pas être utile, d’autant plus que, du sharepoint vue de l’application, tout s’est bien passé. Il peut être utile de transmettre des informations sur l’échec de la connexion à une ressource de journalisation associée à des serveurs, qui pourrait alors filtrer les journaux afin de générer un rapport indiquant la montée et la descente du serveur. .

Je suppose que la raison la plus simple est que vous avez généralement un seul gestionnaire de niveau supérieur qui le fait 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 fondamentalement que c’est une perte de temps dans le traitement des erreurs qui ne vous concernent pas. Mieux vaut laisser l’erreur apparaître dans la stack 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. Catching simplement à la connexion n’est pas utile, car vous pouvez centraliser ce travail plus haut.

Journal et jet de l’OMI est une violation claire du principe de la moindre surprise.

Si l’exception est gérée correctement en amont de la stack d’appels, cela pourrait ne pas valoir une entrée de journal des erreurs. Et puis, il est difficile de trouver une entrée dans le journal des erreurs.