Je travaille en tant qu'entrepreneur qui conçoit une application Java d'entreprise pour mon client dans le rôle de responsable technique. L'application sera utilisée par les utilisateurs finaux et il y aura une équipe de support qui prendra en charge l'application lorsque nous quitterons.
Les autres pistes techniques avec lesquelles je travaille ont l'impression que la gestion des exceptions rendra le code sale. Le système doit lever les exceptions vérifiées uniquement à partir du niveau Service et le reste du code doit lever les exceptions d'exécution de tous les autres niveaux de sorte qu'il n'est pas nécessaire de gérer les exceptions non vérifiées.
Quel est le besoin de lever une exception non contrôlée dans une application métier?
D'après mon expérience dans le passé sur les exceptions d'exécution:
1) Les exceptions non vérifiées rendent le code imprévisible car elles n'apparaissent pas même dans Javadoc.
2) Lancer des exceptions non vérifiées dans une application métier est insensé, car lorsque vous la lancez et que cela va directement sur le visage des utilisateurs, comment l'expliquez-vous à l'utilisateur? J'ai vu assez d'applications Web qui montrent 500 -Internal Error. Contact Administrator
que cela ne signifie rien pour un utilisateur final ou pour l'équipe de support qui gère l'application.
3) Le lancement d'exceptions d'exécution oblige les utilisateurs de la classe qui lancent l'exception à parcourir le code source pour déboguer et voir pourquoi l'exception est levée. Cela ne peut être évité que si le Javadoc de l'exception d'exécution se trouve être parfaitement documenté, ce qui, je trouve, n'est jamais un cas.
la source
@throws
balise, ce qui est d'ailleurs une bonne pratique.@throws
balise Javadoc pour documenter chaque exception non vérifiée qu'une méthode peut lancer, mais n'utilisez pas le mot clé throws pour inclure des exceptions non vérifiées dans la déclaration de méthode.Réponses:
Les exceptions vérifiées sont un expriment échoué dans la conception du langage. Ils vous obligent à avoir des abstractions extrêmement fuyantes et un code sale. Ils doivent être évités autant que possible.
Quant à vos points:
1) Les exceptions vérifiées rendent le code sale et non moins imprévisible car elles apparaissent partout .
2) Comment une exception vérifiée est-elle mieux affichée à l'utilisateur? La seule vraie différence entre les exceptions vérifiées et non contrôlées est technique et n'affecte que le code source.
3) Avez-vous déjà entendu parler de traces de pile? Ils vous indiquent exactement où l'exception a été levée, qu'elle soit cochée ou décochée. En fait, les exceptions vérifiées ont tendance à être pires pour le débogage, car elles sont souvent encapsulées, ce qui conduit à des traces de pile plus longues et plus laides, ou même perdues ensemble parce que l'encapsulation a été mal effectuée.
Il existe deux types d'exceptions: celles qui se produisent "normalement" et sont généralement gérées très près de l'endroit où elles se produisent, et celles qui sont vraiment exceptionnelles et peuvent être gérées de manière générique dans une couche très élevée (il suffit d'annuler l'action en cours et de la consigner / afficher une erreur).
Les exceptions vérifiées étaient une tentative de mettre cette distinction dans la syntaxe du langage au moment où les exceptions sont définies. Les problèmes avec cela sont
la source
SQLException extends Exception
signifie que choisir de lancer unSQLException
car une erreur a à voir avec l'accès à la base de données signifie que l'exception est vérifiée. Et vous pouvez très bien documenter les exceptions non contrôlées dans les commentaires Javadoc. Fonctionne bien pour toutes les autres langues.À mon avis, le type d'exception levée dépend de ce que fait votre code.
Je jette des exceptions vérifiées quand je m'attends à ce qu'elles se produisent assez souvent (les utilisateurs saisissent des données douteuses par exemple) et je m'attends à ce que le code appelant gère la situation.
Je lance des exceptions non vérifiées / d'exécution (pas aussi souvent que vérifiées) lorsque j'ai une situation rare que je ne m'attends pas à ce que le code appelant gère. Un exemple pourrait être une sorte d'erreur bizarre liée à la mémoire que je ne m'attends jamais à se produire. Les types d'erreurs que vous prévoyez de supprimer l'application sont décochés.
Aucune exception ne doit apparaître devant un utilisateur sans un certain niveau de support. Même si c'est juste un "s'il vous plaît couper et coller ce vidage d'erreur dans un e-mail". Rien n'est plus ennuyeux pour un utilisateur que de se faire dire qu'il y a une erreur, mais étant donné qu'aucun détail ni aucune action ne peut être entrepris pour le corriger, il est corrigé.
Je suppose que la philosophie que vous mentionnez provient de l'une des deux sources suivantes:
la source
Si vous ne voulez pas d'exceptions d'exécution non contrôlées, alors pourquoi utilisez-vous java? Il existe la possibilité d'exceptions d'exécution presque partout - notamment les exceptions NullPointerException, ArithmeticException, ArrayIndexOutOfBounds, etc.
Et lorsque vous lisez une fois les fichiers journaux d'un système J2EE, comme, par exemple, une installation SAP NetWeaver, vous verrez que de telles exceptions se produisent littéralement tout le temps.
la source
Il y a quelques règles de gestion des exceptions que vous devez garder à l'esprit. Mais d'abord, vous devez vous rappeler que les exceptions font partie de l'interface exposée par le code; les documenter . Ceci est particulièrement important lorsque l'interface est publique, bien sûr, mais c'est également une très bonne idée dans les interfaces privées.
Les exceptions ne doivent être gérées qu'au point où le code peut faire quelque chose de sensé avec elles. La pire option de manipulation est de ne rien faire du tout à leur sujet, ce qui ne devrait être fait que lorsque c'est exactement la bonne option. (Lorsque j'ai une telle situation dans mon code, j'inclus un commentaire à cet effet afin que je sache ne pas m'inquiéter du corps vide.)
La deuxième pire option consiste à lever une exception sans rapport avec l'original attaché comme cause. Le problème ici est que les informations dans l'exception d'origine qui permettraient de diagnostiquer le problème sont perdues; vous créez quelque chose avec lequel personne ne peut rien faire (à part se plaindre que «cela ne fonctionne pas», et nous savons tous comment nous détestons ces rapports de bogues).
Il est beaucoup mieux de consigner l'exception. Cela permet à quelqu'un de découvrir le problème et de le résoudre, mais vous ne devez enregistrer l'exception qu'au point où elle serait sinon perdue ou signalée via une connexion externe. Ce n'est pas parce que la journalisation plus souvent est un problème majeur en tant que tel, mais plutôt parce qu'une journalisation excessive signifie que le journal consomme plus d'espace sans contenir plus d'informations. Une fois que vous avez enregistré l'exception, vous pouvez signaler une décision précise à l'utilisateur / client avec bonne conscience (tant que vous incluez également l'heure de génération - ou un autre identifiant de corrélation - dans ce rapport afin que la version courte puisse être mise en correspondance avec le détail si nécessaire).
La meilleure option est, bien sûr, de gérer complètement l'exception, en traitant la situation d'erreur dans son intégralité. Si vous pouvez le faire, faites-le! Cela peut même signifier que vous pouvez éviter d'avoir à enregistrer l'exception.
Une façon de gérer une exception consiste à lever une autre exception qui fournit une description de niveau supérieur du problème (par exemple, "
failed to initialize
" au lieu de "index out of bounds
"). C'est un bon schéma tant que vous ne perdez pas les informations sur la cause de l'exception; utilisez l'exception détaillée pour initialiser l'cause
exception de niveau supérieur ou enregistrez le détail (comme expliqué ci-dessus). La journalisation est plus appropriée lorsque vous êtes sur le point de traverser une frontière inter-processus, comme un appel IPC, car il n'y a aucune garantie que la classe d'exception de bas niveau sera présente du tout à l'autre extrémité de la connexion. Le maintien en tant que cause attachée est le plus approprié lors du franchissement d'une frontière interne.Un autre modèle que vous voyez est le catch-and-release:
Il s'agit d'un anti-modèle, sauf si vous avez des contraintes de type provenant d'autres
catch
clauses, ce qui signifie que vous ne pouvez pas laisser passer l'exception par elle-même. Ensuite, ce n'est qu'une laideur de Java.Il n'y a pas de réelle différence entre les exceptions vérifiées et celles non vérifiées, à part le fait que vous devez déclarer les exceptions vérifiées qui franchissent les limites des méthodes. C'est toujours une bonne idée de documenter les exceptions non contrôlées (avec le
@throws
commentaire javadoc) si vous savez qu'elles sont délibérément levées par votre code. Ne jetez pas délibérémentjava.lang.Error
ou ses sous-classes (sauf si vous écrivez une implémentation JVM).Avis: Un cas d'erreur inattendue représente toujours un bug dans votre code. Les exceptions vérifiées sont un moyen de gérer cette menace, et lorsque les développeurs utilisent délibérément des exceptions non contrôlées pour éviter les problèmes de gestion des cas d'erreur, vous accumulez beaucoup de dettes techniques que vous devrez nettoyer un certain temps si vous voulez du code robuste. La gestion des erreurs bâclée n'est pas professionnelle (et regarder la gestion des erreurs est un bon moyen de déterminer à quel point un programmeur est vraiment bon).
la source
Je pense que vous ne devez lever l'exception vérifiée que lorsque l'application peut récupérer. Ainsi, les utilisateurs de votre bibliothèque doivent intercepter ces exceptions et faire ce dont ils ont besoin pour récupérer. Tout le reste doit être décoché.
Par exemple,
Si votre application charge des données à partir d'un fichier ou d'une base de données. Ensuite,..
l'appelant peut toujours intercepter l'exception MissingDataFileException vérifiée, puis essayer de charger les données à partir de la base de données.
la source