Pourquoi de nombreux messages d'exception ne contiennent-ils pas de détails utiles?

220

Il semble y avoir un certain accord sur le fait que les messages d'exception devraient contenir des détails utiles .

Pourquoi de nombreuses exceptions communes aux composants système ne contiennent-elles pas des informations utiles?

Quelques exemples:

  • .NET Listaccès à l'index ArgumentOutOfRangeExceptionne pas me dire la valeur de l' indice qui a été jugé et était invalide et ne me dire la plage autorisée.
  • Fondamentalement, tous les messages d’exception de la bibliothèque standard MSVC C ++ sont totalement inutiles (dans la même veine que ci-dessus).
  • Exceptions Oracle dans .NET vous indiquant (paraphrasé) "TABLE OU VUE introuvable", mais pas laquelle .

Donc, il me semble que la plupart des messages d’exception ne contiennent pas suffisamment de détails pour être utiles. Mes attentes sont-elles hors de propos? Est-ce que j'utilise mal les exceptions et que je le remarque même? Ou peut - être mon impression est fausse: la majorité des exceptions ne fournissent réellement des détails utiles?

Martin Ba
la source
59
Il convient de noter que, du côté des professionnels de la sécurité, "les messages d'erreur ne doivent contenir aucun détail sur les éléments internes du système" est une règle empirique.
Telastyn
118
@Telastyn: Seulement si votre système est ouvert aux attaquants. Si vous utilisez un serveur Web, par exemple, vous souhaitez transmettre des messages d'erreur sans intérêt à l'utilisateur final, mais vous souhaitez néanmoins que les messages d'erreur très détaillés soient consignés de votre côté. Et sur les logiciels côté client, où l'utilisateur n'est pas un attaquant, vous voulez absolument que ces messages d'erreur soient aussi détaillés que possible. Ainsi , en cas de problème et si vous recevez un rapport de bogue, vous avez le maximum d'informations à utiliser. autant que possible, car souvent, c'est tout ce que vous obtenez.
Mason Wheeler
9
@Snowman: Qu'est-ce qui est inaccessible à l'utilisateur s'il s'agit d'un logiciel côté client? Le propriétaire de la machine est propriétaire de la machine et peut tout faire.
Mason Wheeler
6
Il y a toujours des informations supplémentaires que vous aimeriez avoir. Je trouve les messages que vous donnez comme exemples assez bons. Vous pouvez résoudre le problème avec eux. Bien meilleur que "erreur 0x80001234" (exemple inspiré de Windows Update).
usr

Réponses:

204

Les exceptions ne contiennent pas de détails utiles car le concept des exceptions n'a pas encore suffisamment mûri dans la discipline du génie logiciel, de sorte que de nombreux programmeurs ne les comprennent pas complètement et ne les traitent donc pas correctement.

Oui, IndexOutOfRangeExceptiondevrait contenir l'index précis qui était hors de portée, ainsi que la plage qui était valide au moment où il a été lancé, et il est méprisable pour le compte des créateurs du runtime .NET qu'il n'en a pas. Oui, l’ table or view not foundexception d’Oracle doit contenir le nom de la table ou de la vue qui n’a pas été trouvée et, encore une fois, le fait qu’elle ne soit pas méprisable au nom de celui qui en est responsable.

La confusion provient en grande partie de l'idée originale erronée selon laquelle les exceptions devraient contenir des messages lisibles par l'homme, ce qui découle d'un manque de compréhension de ce que sont les exceptions, il s'agit donc d'un cercle vicieux.

Puisque les gens pensent que l’exception devrait contenir un message lisible par l’homme, ils sont convaincus que toute information transportée par l’exception devrait également être formatée en un message lisible par l’homme, puis ils sont ennuyés d’écrire tout le message lisible par l’homme. code du bâtiment, ou craignent que cela ne divulgue une quantité déconseillée d'informations à tous les regards indiscrets qui pourraient voir le message. (Les problèmes de sécurité mentionnés par d'autres réponses.)

Mais la vérité est qu’ils ne devraient pas s’inquiéter de cela, car l’exception ne devrait pas contenir un message lisible par l’homme. Les exceptions sont des choses que seuls les programmeurs devraient voir et / ou traiter. S'il est toujours nécessaire de présenter des informations sur les défaillances à un utilisateur, vous devez le faire à un niveau très élevé, de manière sophistiquée et dans la langue de l'utilisateur, qui, statistiquement, a peu de chances d'être l'anglais.

Ainsi, pour nous programmeurs, le "message" de l'exception est le nom de la classe de l'exception , et toute autre information pertinente à l'exception doit être copiée dans les variables membres (final / en lecture seule) de l'objet exception. De préférence, chaque petit morceau imaginable. De cette façon, aucun message n’a besoin (ou ne devrait) être généré, et donc aucun regard ne peut le voir.

Pour répondre à la préoccupation exprimée par Thomas Owens dans un commentaire ci-dessous:

Oui, bien sûr, à un certain niveau, vous allez créer un message de journal au sujet de l'exception. Mais vous voyez déjà le problème avec ce que vous dites: d'un côté, un message de journal d'exception sans trace de pile est inutile, mais d'un autre côté, vous ne voulez pas que l'utilisateur voie l'intégralité du tracé de la pile des exceptions. Encore une fois, notre problème ici est que notre perspective est faussée par les pratiques traditionnelles. Les fichiers journaux sont traditionnellement en texte brut, ce qui était peut-être correct alors que notre discipline en était à ses balbutiements, mais peut-être plus maintenant: s'il existe un problème de sécurité, le fichier journal doit être binaire et / ou crypté.

Que ce soit en binaire ou en texte brut, le fichier journal doit être considéré comme un flux dans lequel l'application sérialise les informations de débogage. Un tel flux serait réservé aux yeux des programmeurs, et la tâche de générer des informations de débogage pour une exception devrait être aussi simple que la sérialisation de l'exception dans le flux de journal de débogage. De cette façon, en consultant le journal, vous voyez le nom de la classe d’exception (qui, comme je l’ai déjà dit, est à toutes fins pratiques "le message",) chacune des variables de membre d’exception qui décrivent tout ce qui est pertinent. et-pratique-à-inclure-dans-un-journal, et la trace entière de la pile. Notez que la mise en forme d'un message d'exception lisible par l'homme est visiblement absente de ce processus.

PS

Cette réponse contient quelques autres réflexions sur ce sujet: comment rédiger un bon message d’exception

PPS

Il semble que beaucoup de gens étaient cochés par ma suggestion sur les fichiers journaux binaires, donc je modifie la réponse une fois de plus pour le rendre encore plus clair que ce que je veux dire ici est pas que le fichier journal doit être binaire, mais le fichier journal peut être binaire, si besoin est.

Mike Nakis
la source
4
J'ai examiné certaines des classes d'exceptions du .NET Framework et il s'est avéré qu'il existe de nombreuses possibilités d'ajouter ce type d'informations par programme. Donc, je suppose que la question se résume à "pourquoi ne le font-ils pas?" Mais +1 pour tout ce qui est "lisible par l'homme".
Robert Harvey
7
Je ne suis pas d'accord que les exceptions ne devraient pas contenir un composant lisible par l'homme. À un certain niveau, vous souhaiterez peut-être créer un message de journal concernant l'exception. Je dirais que la journalisation d'une trace de pile dans un fichier journal lisible par l'utilisateur expose les détails de l'implémentation que vous ne voulez pas exposer. Le message lisible par l'homme doit donc être consigné. Lorsqu'ils se voient présenter le fichier journal contenant l'erreur, les développeurs doivent avoir un point de départ pour commencer leur débogage et pouvoir forcer l'exception à se produire. Le composant lisible par l’homme doit être détaillé de manière appropriée sans donner de mise en œuvre.
Thomas Owens
44
alors les programmeurs ne sont pas humains? En regardant mes collègues, cela confirme les soupçons que je porte depuis un certain temps ...
gbjbaanb
51
Encore une fois, il n’ya rien de mal à laisser l’utilisateur voir la trace entière de la pile , tant que le logiciel est côté client. Chaque projet logiciel professionnel sur lequel j'ai travaillé, et la plupart des projets amateurs, contenait également un système de journalisation générant un vidage complet des erreurs lorsqu'une exception non gérée était déclenchée, y compris des traces de pile complètes de tous les threads en cours d'exécution dans le répertoire. processus. Et l'utilisateur pouvait (haletant, oh horreur!) Le regarder à tout moment, étant donné que c'était nécessaire (pas simplement utile, mais nécessaire ) pour nous renvoyer le message d'erreur! Quel est le problème avec ça?
Mason Wheeler
13
Je ne suis pas non plus convaincu par les fichiers journaux uniquement binaires . Principalement à cause de mon expérience avec systemd. Son outil spécial pour consulter ces journaux est assez déroutant et semble avoir été conçu par un comité composé de singes de Shakespeare. Considérez que, pour une application Web, la première personne à voir votre exception sera souvent l'administrateur système , et il va vouloir déterminer s'il s'agit d'un problème à réparer (par exemple, le disque manque d'espace) ou à renvoyer aux développeurs.
Michael Hampton
46

Pourquoi de nombreuses exceptions communes aux composants système ne contiennent-elles pas des informations utiles?

D'après mon expérience, il existe un certain nombre de raisons pour lesquelles les exceptions ne contiennent pas d'informations utiles. Je m'attends à ce que ces types de raisons s'appliquent également aux composants du système - mais je ne le sais pas avec certitude.

  • Les personnes axées sur la sécurité voient les exceptions comme une source de fuite d'informations (par exemple ). Comme le comportement par défaut des exceptions consiste à afficher ces informations à l'utilisateur, les programmeurs sont parfois prudents.
  • En C ++, j'ai entendu des arguments contre l'allocation de mémoire dans des blocs catch (où au moins une partie du contexte permet de créer de bons messages). Cette allocation est difficile à gérer et, pire encore, peut entraîner une exception de mémoire insuffisante, provoquant souvent le blocage de votre application ou une fuite de mémoire. Il est difficile de bien formater les exceptions sans allouer de mémoire, et cette pratique a peut-être migré d'une langue à l'autre, contrairement aux programmeurs.
  • Ils ne savent pas. Je veux dire, il y a des scénarios où le code n'a aucune idée de ce qui a mal tourné. Si le code ne sait pas - il ne peut pas vous dire.
  • J'ai travaillé dans des endroits où les problèmes de localisation empêchaient d'insérer des chaînes en anglais uniquement dans le système, même pour des exceptions qui ne seraient lues que par le personnel de soutien anglophone.
  • Certains endroits, j'ai vu des exceptions utilisées plus comme des assertions. Ils sont là pour transmettre un message clair et fort au cours du développement indiquant que quelque chose n'a pas été fait ou qu'un changement a été apporté à un endroit, mais pas à un autre. Celles-ci sont souvent assez uniques pour qu'un bon message soit un effort dupliqué ou simplement déroutant.
  • Les gens sont paresseux, les programmeurs plus que la plupart. Nous passons beaucoup moins de temps sur le chemin exceptionnel que sur le chemin joyeux, et c'est un effet secondaire.

Mes attentes sont-elles hors de propos? Est-ce que j'utilise mal Exceptions et que je le remarque même?

Kinda? Je veux dire, les exceptions devraient avoir des messages gentils, mais ce sont aussi des exceptions . Vous devriez passer votre temps à concevoir du code pour éviter des conditions exceptionnelles ou à l'écrire pour gérer des conditions exceptionnelles (en ignorant le message), sans les utiliser comme une sorte de mécanisme de retour d'informations interactif lors de la programmation. Il est inévitable de les utiliser à des fins de débogage, mais dans la plupart des situations, cela devrait être réduit au minimum. Le fait que vous remarquiez ce problème me fait craindre de ne pas le prévenir suffisamment.

Telastyn
la source
Je sais que cela a été étiqueté C, mais je dois ajouter que votre dernier paragraphe ne s'applique pas à toutes les langues, car certaines peuvent (à tort ou à raison) se fier fortement à la gestion et au compte rendu des erreurs basés sur des exceptions .
Lilienthal
1
@ Lilienthal - comme? Aucune langue que je connais très bien ne fait ce genre de choses régulièrement.
Telastyn
1
Je pense que cette réponse a beaucoup de bon contenu, mais elle évite de dire la ligne du bas, qui est "Ils devraient."
djechlin
3
Merci. Votre inquiétude est sans fondement (j'espère :-). Mais chaque fois que je passe une minute supplémentaire à rechercher ce qui ne va pas dans ce test unitaire ou à passer plus de temps à analyser le code parce que le fichier journal manque d’informations, je suis un peu ennuyé par la piètre qualité évitable de certains messages :-)
Martin Ba
ABT propriétaire de SAP @Telastyn a une structure de classe d'exception pouvant contenir un message, qui est essentiellement un objet spécifiquement destiné à signaler à l'utilisateur l'état du programme (réussite, échec, avertissement) avec un message dynamique (multilingue). J'admets que je ne sais pas à quel point ce genre de choses est répandu, ou si c'est même encouragé dans les langues, c'est possible, mais il y en a au moins une où c'est (malheureusement) une pratique courante.
Lilienthal
12

Je n'ai pas une expérience excessive de C #, ni du C ++ en particulier, mais je peux vous dire ceci: les exceptions écrites par le développeur sont 9 fois plus utiles que toute exception générique que vous trouverez jamais, point à la ligne.

Idéalement, une exception générique vous indiquera exactement pourquoi l'erreur s'est produite et vous pourrez y remédier facilement, mais de manière réaliste, dans les applications volumineuses avec plusieurs classes pouvant générer une grande variété d'exceptions, ou Même type d'exceptions, il est toujours plus utile d'écrire votre propre sortie pour le retour d'erreur que de s'en remettre au message par défaut.

C’est ce qui devrait être fait, car comme beaucoup de personnes l’ont souligné, certaines applications ne veulent pas envoyer de message d’erreur qu’elles ne veulent pas que l’utilisateur voie, pour des raisons de sécurité ou pour éviter toute confusion.

Au lieu de cela, vous devez anticiper dans votre conception les types d'erreur pouvant être générés dans votre application (il y aura toujours des erreurs) et rédiger des messages d'erreur qui vous aideront à identifier le problème.

Cela ne vous aidera pas toujours - car vous ne pouvez pas toujours anticiper quel message d'erreur sera utile - mais c'est la première étape pour mieux comprendre votre propre application à long terme.

Zibbobz
la source
7

La question est précisément de savoir pourquoi tant d’exceptions levées par les "composants système" (ou classes de bibliothèque standard) ne contiennent pas de détails utiles.

Malheureusement, la plupart des développeurs n'écrivent pas les composants de base dans des bibliothèques standard, pas plus que les documents de conception détaillés ou autres motifs de conception ne sont nécessairement rendus publics. En d'autres termes, nous pouvons ne jamais savoir avec certitude.

Cependant, il convient de garder à l'esprit deux points essentiels pour lesquels des informations détaillées sur les exceptions pourraient ne pas être souhaitables ou importantes:

  1. Une exception peut être utilisée en appelant du code de quelque manière que ce soit: une bibliothèque standard ne peut pas imposer de contraintes sur la manière dont l'exception est utilisée. Plus précisément, il peut être affiché à l'utilisateur. Considérons un index de tableau hors limites: ceci peut fournir des informations utiles à un attaquant. Le concepteur de langage n'a aucune idée de la manière dont une application utilisera l'exception levée ni même du type d'application (par exemple, une application Web ou un poste de travail). Par conséquent, la suppression d'informations peut être plus sûre du point de vue de la sécurité.

  2. Les exceptions ne doivent pas être affichées à l'utilisateur. Au lieu de cela, affichez un message d'erreur convivial et enregistrez l'exception à un emplacement auquel un attaquant n'a pas accès (le cas échéant). Une fois que l'erreur est identifiée, le développeur doit déboguer le code, en inspectant les cadres de pile et les chemins logiques. À ce stade, le développeur dispose de plus d'informations qu'une exception ne pourrait jamais espérer en avoir.


la source
3
1. Sur la base de ce critère, les informations qui apparaissent ("Index hors limites", trace de pile) semblent relativement arbitraires et ne sont pas affichées (valeur de l'index). 2. Le débogage peut potentiellement être beaucoup plus rapide et plus facile lorsque des valeurs dynamiques pertinentes sont connues. Par exemple, il vous dira souvent immédiatement si le problème est lié à la saisie de déchets dans le code qui a échoué ou si le code ne traite pas correctement une bonne saisie
Ben Aaronson
@BenAaronson l'identité / classe de l'exception nous indique le type d'erreur. Mon point est que les détails peuvent être omis (c.-à-d. Quelle valeur spécifique a causé l'erreur) pour la sécurité. Cette valeur peut être identifiée par l'utilisateur, ce qui permet de révéler des informations à un attaquant.
@ Snowman Je pense à peine que la sécurité est un facteur à prendre en compte lorsqu'une trace de pile complète est disponible, contrairement au numéro d'index. Bien sûr, je comprends un attaquant qui recherche les dépassements de mémoire tampon, mais de nombreuses exceptions laissent également des données assez sûres (par exemple, quelle table Oracle n'a pas été trouvée)
gbjbaanb
@ gbjbaanb qui a dit que nous devions montrer la trace complète de la pile à l'utilisateur?
1
Merci de partager cette idée. Personnellement, je ne suis pas d’accord et pense que l’argument de la sécurité est une erreur totale, mais c’est peut-être une justification.
Martin Ba
4

Tout d’abord, permettez-moi de faire éclater une bulle en affirmant que, même si le message diag est chargé avec des informations qui vous amènent à la ligne de code exacte et à la sous-commande en 4 secondes, il est probable que les utilisateurs ne l’écriront jamais ou ne le transmettra pas au support technique. et on vous dira "Eh bien, il est dit quelque chose à propos d'une violation ... Je ne sais pas si ça avait l'air compliqué!"

J'écris des logiciels et j'appuie les résultats d'autres logiciels depuis plus de 30 ans maintenant. Personnellement, la qualité actuelle d'un message d'exception n'a pratiquement rien à voir avec la sécurité, quelle que soit la manière dont les résultats finaux sont apparus. l'univers, beaucoup plus à voir avec le fait que tant de personnes de notre secteur étaient autodidactes à l'origine et qu'elles n'incluaient jamais de leçons de communication. Peut-être que si nous obligions tous les nouveaux codeurs à occuper un poste de maintenance pendant deux ou trois ans, afin de pouvoir déterminer ce qui n'allait pas, ils comprendraient au moins l'importance d'une certaine précision.

Récemment, dans une application en cours de reconstruction, il a été décidé que les codes de retour appartiendraient à l'un des trois groupes suivants:

  • 0 à 9 serait le succès grâce au succès avec des informations supplémentaires.
  • 10 à 99 seraient des erreurs non fatales (récupérables), et
  • 101 à 255 seraient des erreurs fatales.

(100 a été laissé pour une raison quelconque)

Dans un flux de travail particulier, nous pensions être réutilisés ou le code générique utiliserait les retours génériques (> 199) pour les erreurs fatales, nous laissant ainsi 100 erreurs fatales possibles pour un flux de travail. Avec des données légèrement différenciantes dans le message, les erreurs telles que le fichier non trouvé peuvent toutes utiliser le même code et se différencier des messages.

Lorsque le code a été renvoyé par les sous-traitants, vous ne croiriez pas notre surprise lorsque pratiquement TOUTES LES ERREURS FATALES SIMPLES étaient le code de retour 101.

Tout ce qui a été pris en compte, je pense que la réponse à votre question est que les messages n’ont aucune signification, car lors de leur création, ils devaient constituer des espaces réservés auxquels personne ne revenait. Finalement, les gens ont compris comment résoudre les problèmes non pas à cause des messages, mais de les DISPITER.

Depuis ce temps, les autodidactes n'ont tout simplement jamais eu un bon exemple de ce qu'une exception devrait contenir. Ajoutez à cela plus d'utilisateurs ne lisent pas les messages, encore moins d'essayer de les transmettre au support (j'ai vu des messages d'erreur copiés et collés par les utilisateurs utilisés qui ont ensuite été expurgés avant d'être envoyés avec le commentaire ultérieur semblait être une mine d’informations et je ne pouvais absolument pas tout vouloir, alors ils en ont retiré au hasard un tas.

Et regardons les choses en face, avec beaucoup trop (pas trop, beaucoup) de la prochaine génération de codeurs, si cela demande plus de travail et n’ajoute pas de flash, cela ne vaut tout simplement pas la peine ...

Dernière remarque: si un message d'erreur inclut un code d'erreur / de retour, il me semble que quelque part dans les modules exécutés, il devrait exister une ligne se lisant comme "if condition return code-value" et que condition devrait vous expliquer pourquoi le code de retour eu lieu. Cela semble être une approche logique simple, mais pour la vie, essayez simplement de demander à Microsoft de vous dire ce qui s’est passé lorsqu’une mise à niveau de Windows a échoué avec le CODE 80241013 ou un autre identifiant très unique. Un peu triste, n'est-ce pas?

Excité
la source
8
"... vous ne croiriez pas à notre surprise quand pratiquement TOUTES LES ERREURS FATALES UNIQUES étaient le code de retour 101." Vous avez raison. Je ne crois pas que vous ayez été surpris lorsque l'entrepreneur a suivi vos instructions.
Odalrick
3
chances are the users will never write it down... and you will be told "Well it said something about a violation..." C'est pourquoi vous utilisez un outil de journalisation des exceptions pour générer automatiquement le rapport d'erreur contenant la trace de pile et éventuellement même l'envoyer à votre serveur. J'ai eu un utilisateur une fois qui n'était pas très technique. Chaque fois qu'elle envoyait un message à partir du journal des erreurs, le message "Je ne suis pas sûr de ce que j'ai mal fait, mais ..." peu importe le nombre de fois où j'ai expliqué que cette erreur signifiait que le bogue était de mon côté . Mais j'ai toujours eu les rapports d'erreur d'elle!
Mason Wheeler
3

Bien que je convienne que les exceptions devraient contenir autant d’informations que possible, ou du moins être moins génériques. Dans le cas table non trouvée, le nom de la table serait bien.

Mais vous en savez plus sur ce que vous tentiez de faire à la place du code où vous avez reçu l'exception. Bien que, souvent, vous ne puissiez vraiment rien faire pour rectifier la situation lorsque quelque chose ne va pas dans une bibliothèque en dehors de votre contrôle, vous pouvez ajouter des informations beaucoup plus utiles sur la situation dans laquelle une chose a mal tourné.

Dans le cas d'une table non trouvée, cela ne vous aidera pas beaucoup si on vous dit que la table introuvable est appelée ÉTUDIANTS, car vous n'avez pas une telle table et que cette chaîne ne figure nulle part dans votre code.

Mais si vous attrapez l'exception et la relancez avec l'instruction SQL que vous avez essayé d'exécuter, vous serez mieux loti, car il s'avère que vous avez essayé d'insérer un enregistrement dont le champ de nom est Robert '); DROP TABLE ÉTUDIANTS; (Il y a toujours un xkcd!)

Donc, pour lutter contre les exceptions moins qu'informatives: essayez-rattraper-relancer avec plus d'informations spécifiques à ce que vous tentiez de faire.

Je devrais probablement ajouter, pour que cela réponde davantage au pourquoi de la question, qu’une raison probable pour laquelle les responsables des bibliothèques n’ont pas cherché à améliorer les messages relatifs aux exceptions, c’est qu’ils ne savent pas pourquoi quelque chose a été essayé qui a échoué, cette logique est dans le code appelant.

Courbé
la source
Par exemple, en C ++, vous devriez en utiliser throw_with_nestedbeaucoup.
Miles Rout
3

Pour donner une réponse légèrement différente: Le code incriminé a probablement été créé pour spécifier:

  • La fonction reçoit X et retourne Y
  • Si X est invalide, lève l'exception Z

Ajoutez la pression qui vous incite à respecter exactement les spécifications (par crainte d’être rejetée lors des révisions / tests) en un temps minimum et avec un minimum de complications, vous disposez alors de votre recette pour une exception de bibliothèque entièrement conforme et inutile.

Stu Pegg
la source
3

Les exceptions ont un coût spécifique à la langue et à la mise en œuvre.

Par exemple, des exceptions C ++ sont nécessaires pour détruire toutes les données actives entre la projection d'une trame d'appel et la capture d'une trame d'appel, ce qui est coûteux. Par conséquent, les programmeurs ne souhaitent pas utiliser beaucoup les exceptions.

Dans Ocaml, le lancement d'une exception est presque aussi rapide qu'un C setjmp(son coût ne dépend pas du nombre de trames d'appel traversées), ce qui permet aux développeurs de l'utiliser beaucoup (même dans des cas non exceptionnels et très courants). En revanche, les exceptions C ++ sont suffisamment lourdes pour que vous ne les utilisiez probablement pas beaucoup comme vous le feriez dans Ocaml.

Un exemple typique est une recherche ou une exploration récursive qui peut être "arrêtée" dans une récursion assez profonde (par exemple, trouver une feuille dans un arbre ou une fonction d'unification). Dans certaines langues, il est plus rapide (donc plus idiomatique) de propager cette condition à chaque appelant. Dans d'autres langues, le lancement d'une exception est plus rapide.

Ainsi, en fonction de la langue (et des habitudes des développeurs qui l’utilisent), une exception pourrait contenir beaucoup de détails utiles ou, au contraire, être utilisée comme un saut rapide non local et ne porter que les données très utiles.

Basile Starynkevitch
la source
6
"Par exemple, les exceptions C ++ sont nécessaires pour détruire toutes les données actives entre le lancement de la trame d'appel et la capture de la trame d'appel, et cela coûte cher. Par conséquent, les programmeurs ne souhaitent pas utiliser beaucoup d'exceptions." Merde totale. La principale force des exceptions C ++ est que les destructeurs sont appelés déterministes. Personne ne les utiliserait s'ils sautaient juste.
Miles Rout
Je le sais, mais c’est un fait que les exceptions C ++ ne ressemblent pas à Ocaml et que vous ne les utilisez pas comme vous le faites dans Ocaml.
Basile Starynkevitch
5
Vous n'utilisez pas les exceptions C ++ pour le flux de contrôle en C ++ principalement parce que cela rend le code illisible et difficile à comprendre.
Miles Rout
-2

Qu'est-ce qui vous fait penser que la valeur d'index ou la plage requise ou le nom de la table est un détail utile, pour une exception?

Les exceptions ne sont pas un mécanisme de traitement des erreurs; ils sont un mécanisme de récupération .

Le point d'exception est de remonter jusqu'au niveau de code pouvant gérer l'exception. Où que ce soit, vous avez les informations nécessaires ou elles ne sont pas pertinentes. Si vous avez besoin d'informations sans y avoir accès immédiatement , vous ne gérez pas l'exception au niveau approprié.

La seule fois où je peux penser à des informations supplémentaires qui pourraient être utiles est au plus haut niveau absolu de votre application où vous plantez et émettez un vidage d’erreurs; mais ce n’est pas le travail de l’exception d’accéder, de compiler et de stocker ces informations.

Je ne dis pas que vous pouvez simplement mettre "lancer une nouvelle exception" partout et l'appeler "bon", il est possible d'écrire de mauvaises exceptions. Mais inclure des informations non pertinentes n’est pas nécessaire de les utiliser correctement.

Odalrick
la source
Je ne décrirais pas le nom de la table de base de données manquante comme non pertinent bien que je comprenne et comprenne le point que vous avancez. Je vous ai donné un vote positif.
Daniel Hollinrake
1
@ DanielHollinrake Oui, le nom de la table est certainement le moins pertinent des exemples. Dans le code avec lequel je travaille, ce genre de problème est extrêmement courant et le fait de voir comment le nom de la table a été mutilé donne des indices sur ce qui ne va pas. J'ai essayé de penser à un exemple pour expliquer pourquoi ces choses sont sans importance pour l'exception; peut-être que je peux utiliser ça ...
Odalrick
Je ne suis pas d'accord. Pour la gestion d'une exception, des détails supplémentaires peuvent ne pas être requis, car vous souhaitez simplement protéger l'application contre les pannes, mais vous devrez enfin expliquer pourquoi cela n'a pas fonctionné et pouvoir y remédier. Si vous n'avez pas d'indice mais le type d'exception, alors regardez bien le débogage.
T3chb0t
@ t3chb0t C’est à cela que servent la trace de pile et la classe de l’exception, le vidage de la mémoire et tout le reste. Comment cela vous aiderait- il si un client appelle et dit: "L'ordinateur me dit qu'il a essayé d'accéder à l'index 5 et que ce n'était pas là." Cela ne peut aider que si vous sérialisez également la liste, le contexte de la liste et tout ce qui pourrait être utile. Vous ne devez pas sérialiser l'état complet de l'application chaque fois que vous générez une exception.
Odalrick
@Odalrick pour le client, cela n'a peut-être pas de sens, mais en tant que développeur, j'apprécie toutes les informations que je peux obtenir ;-), alors peut-être un autre exemple: disons qu'un SqlExeption se produit et c'est tout ce que vous savez ... Il est beaucoup plus facile de le réparer . si vous savez quelle chaîne de connexion, base de données ou table, etc. n'a pas fonctionné ... et ceci est d'autant plus important si votre application utilise plusieurs bases de données. Une trace de pile détaillée nécessite que les fichiers pdb soient fournis avec l'application ... ce n'est pas toujours possible. De plus, les images mémoire peuvent devenir très volumineuses et ne peuvent pas toujours être transférées.
T3chb0t