J'ai rencontré un débat entre quelques amis et moi. Ils préfèrent les exceptions générales telles que ClientErrorException
et ServerErrorException
avec détail comme champs de l'exception, alors que je préfère rendre les choses plus spécifiques. Par exemple, je pourrais avoir une poignée d'exceptions comme:
BadRequestException
AuthenticationFailureException
ProductNotFoundException
Chacun de ces éléments est basé sur le code d'erreur renvoyé par l'API.
Suivant les avantages des exceptions, cela semble idiomatique pour Java. Cependant, l'opinion de mes amis n'est pas tout à fait rare.
Existe-t-il un moyen préféré en termes de lisibilité du code et de convivialité de l'API, ou est-ce vraiment une question de préférence?
abstract
et généraliser des classes d'exceptions avec les méthodes getter, puis faire en sorte que les classes granulaires étendent les classes générales. Par exempleAuthenticationFaliureException extends ClientErrorException
. De cette façon, chaque utilisateur peut choisir comment il souhaite gérer les exceptions. Mais ça marche plus, évidemment. Cependant, lors de l'écriture d'une application (au lieu d'une bibliothèque), c'est une situation différente à mon humble avis. Dans ce cas, je ne rendrais pas les exceptions plus granulaires que vous n'en avez besoin, par souci de simplicité.Réponses:
La principale différence entre avoir de nombreuses classes d'exceptions différentes et n'en avoir que quelques-unes, avec des informations plus détaillées dans le texte d'erreur (par exemple), est que de nombreuses classes d'exceptions différentes permettent au code appelant de réagir différemment à différents types d'erreurs, tout en ayant Seules quelques classes facilitent la gestion uniforme de toutes sortes d'exceptions.
Il s'agit généralement d'un compromis. Il peut être atténué dans une certaine mesure en utilisant l'héritage (une classe d'exception de base générale pour les appelants qui veulent tout capturer et consigner tout de manière générique, et des exceptions dérivées de cette classe de base pour les appelants qui ont besoin de réactions différentes), mais même cela peut produire un beaucoup de complexité inutile si vous ne faites pas attention et respectez le principe YAGNI. La question directrice devrait donc être ici:
Il n'y a pas de solution unique à cela, pas de «meilleure pratique» braindead que vous pouvez appliquer partout. La réponse à cette question dépend fortement du type de logiciel ou de composant que vous concevez:
une application, où vous ou l'équipe avez toute la base de code sous votre contrôle?
ou un composant réutilisable pour des tiers, où vous ne connaissez pas tous les appelants potentiels?
une application serveur de longue durée, où différents types d'erreurs ne devraient pas immédiatement briser l'ensemble du système et peuvent nécessiter différents types d'atténuation des erreurs?
un processus d'application de courte durée où il suffit en cas d'erreur d'afficher un message d'erreur à l'utilisateur puis de redémarrer le processus?
Donc, plus vous en savez sur les appelants potentiels de votre composant, mieux vous pouvez décider du niveau de détail correct pour vos exemptions.
la source
La réponse dépend du niveau de rapport d'erreur dont nous parlons.
En général, je suis d'accord avec vos amis, vous ne devriez pas les rendre plus granuleux que nécessaire pour transmettre la cause du problème.
S'il existe une exception courante et bien connue pour référencer null (NullReferenceException), vous ne devez pas créer votre propre MyObjectIsNullException. Cela ne ferait qu'ajouter une couche de confusion pour l'interprète humain, une chose supplémentaire à apprendre qui ne clarifie rien.
Ce n'est que lorsque votre exception est si spéciale qu'il n'y en a pas de prédéfinie qui couvre la cause racine que vous devez créer la vôtre.
Cependant, vous ne devez pas vous arrêter là. L'erreur courante peut se produire dans l'un de vos composants et vous souhaiterez peut-être signaler qu'il y avait un problème dans votre composant . Donc, pas seulement ce qui s'est mal passé, mais aussi où. Il serait alors approprié d'envelopper la première exception dans une MyComponentException. Cela vous donnera le meilleur des deux mondes.
Tout d'abord, il est clair que votre composant a rencontré des problèmes. Sur un levier inférieur, la cause spécifique serait dans l'exception intérieure.
la source