Si une langue prend en charge les exceptions de manière inhérente, il est préférable de lancer des exceptions et les clients peuvent intercepter l’exception s’ils ne souhaitent pas qu’il en résulte un échec. En fait, les clients de votre code attendent des exceptions et rencontreront de nombreux bogues car ils ne vérifieront pas les valeurs de retour.
L'utilisation d'exceptions si vous avez le choix présente de nombreux avantages.
messages
Les exceptions contiennent des messages d'erreur lisibles par l'utilisateur, qui peuvent être utilisés par les développeurs pour le débogage ou même affichés pour les utilisateurs, le cas échéant. Si le code consommateur ne peut pas gérer l'exception, il peut toujours le consigner pour que les développeurs puissent consulter les journaux sans avoir à s'arrêter à chaque trace pour déterminer la valeur renvoyée et la mapper dans un tableau pour déterminer le résultat. exception réelle.
Avec les valeurs de retour, aucune information supplémentaire ne peut être facilement fournie. Certaines langues prennent en charge les appels de méthode pour obtenir le dernier message d'erreur. Cette préoccupation est donc quelque peu apaisée, mais cela oblige l'appelant à faire des appels supplémentaires et nécessite parfois l'accès à un "objet spécial" contenant ces informations.
Dans le cas de messages d'exception, je fournis autant de contexte que possible, tels que:
Une stratégie du nom "foo" n'a pas pu être extraite pour l'utilisateur "bar", qui a été référencé dans le profil de l'utilisateur.
Comparez cela à un code de retour -85. Lequel préfèrerais tu?
Piles d'appels
Les exceptions ont généralement également des piles d'appels détaillées qui aident à déboguer le code plus rapidement et plus rapidement, et peuvent également être enregistrées par le code appelant si elles le souhaitent. Cela permet aux développeurs d’identifier le problème généralement à la ligne exacte, ce qui le rend très puissant. Encore une fois, comparez cela à un fichier journal avec des valeurs de retour (telles que -85, 101, 0, etc.), laquelle préféreriez-vous?
Échec approche rapide biaisée
Si une méthode appelée quelque part qui échoue, elle lève une exception. Le code appelant doit supprimer explicitement l'exception sinon il échouera. J'ai trouvé cela étonnant, car lors du développement et des tests (et même en production), le code échoue rapidement, obligeant les développeurs à le réparer. Dans le cas de valeurs de retour, si une vérification de la valeur de retour est manquée, l'erreur est ignorée en silence et le bogue fait surface quelque chose d'inattendu, généralement avec un coût beaucoup plus élevé de débogage et de réparation.
Exceptions d'emballage et de désemballage
Les exceptions peuvent être encapsulées dans d'autres exceptions, puis décomposées si nécessaire. Par exemple, votre code peut indiquer ArgumentNullException
lequel le code appelant peut être intégré à une ligne UnableToRetrievePolicyException
car cette opération a échoué dans le code appelant. Même si un message semblable à l'exemple que j'ai fourni ci-dessus peut être affiché à l'utilisateur, un code de diagnostic peut décompresser l'exception et indiquer qu'il en ArgumentNullException
est à l'origine du problème, ce qui signifie qu'il s'agit d'une erreur de codage dans le code de votre consommateur. Cela pourrait alors déclencher une alerte afin que le développeur puisse corriger le code. De tels scénarios avancés ne sont pas faciles à implémenter avec les valeurs de retour.
Simplicité du code
Celui-ci est un peu plus difficile à expliquer, mais j'ai appris grâce à ce codage avec des valeurs de retour et des exceptions. Le code écrit à l'aide des valeurs de retour passe généralement un appel, puis une série de vérifications sur la valeur de retour. Dans certains cas, il ferait appel à une autre méthode et disposerait désormais d'une autre série de contrôles pour les valeurs renvoyées par cette méthode. À quelques exceptions près, la gestion des exceptions est beaucoup plus simple dans la plupart des cas. Vous avez un bloc try / catch / finally, le moteur d’exécution faisant de son mieux pour exécuter le code dans les blocs finally pour le nettoyage. Même les blocs try / catch / finally imbriqués sont relativement plus faciles à suivre et à gérer que si les options imbriquées / / et les valeurs renvoyées associées provenant de plusieurs méthodes.
Conclusion
Si la plate-forme que vous utilisez prend en charge les exceptions (notamment Java ou .NET), vous devez alors bien supposer qu'il n'y a pas d'autre moyen que de lever des exceptions car ces plateformes ont pour règle de générer des exceptions, et vos clients s'attendent à ce qu'ils alors. Si j'utilisais votre bibliothèque, je ne prendrais pas la peine de vérifier les valeurs de retour car je m'attendais à des exceptions, c'est ainsi que le monde est sur ces plates-formes.
Cependant, s'il s'agissait de C ++, il serait un peu plus difficile à déterminer car une grande base de code existe déjà avec des codes de retour, et un grand nombre de développeurs sont à l'écoute pour renvoyer des valeurs plutôt que des exceptions (par exemple, Windows est en proie à HRESULTs) . En outre, dans de nombreuses applications, cela peut également être un problème de performances (ou du moins, être perçu comme tel).
try
/catch
existe pour. De plus, vous pouvez placer votretry
/catch
beaucoup plus loin dans la pile dans un endroit plus approprié pour la traiter (ce qui permet une plus grande séparation des problèmes).