Je reste simple.
Une bibliothèque a un type d'exception de base étendu à partir de std ::: runtime_error (qui provient de C ++ s'applique comme approprié à d'autres langages). Cette exception prend une chaîne de message pour que nous puissions nous connecter; chaque point de lancement a un message unique (généralement avec un ID unique).
C'est à peu près ça.
Remarque 1 : dans les situations où une personne interceptant l'exception peut corriger les exceptions et redémarrer l'action. J'ajouterai des exceptions dérivées pour les choses qui peuvent potentiellement être corrigées de manière unique à un emplacement distant. Mais cela est très très rare (rappelez-vous que le receveur est peu susceptible d'être proche du point de lancer, donc résoudre le problème va être difficile (mais tout dépend de la situation)).
Remarque 2 : Parfois, la bibliothèque est si simple qu'elle ne vaut pas la peine de lui donner sa propre exception et std :: runtime_error fera l'affaire. Il n'est important d'avoir une exception que si la possibilité de la distinguer de std :: runtime_error peut donner à l'utilisateur suffisamment d'informations pour faire quelque chose avec.
Remarque 3 : Dans une classe, je préfère généralement les codes d'erreur (mais ceux-ci ne s'échapperont jamais dans l'API publique de ma classe).
En regardant vos compromis:
Les compromis que je vois comprennent:
Plus de classes d'exceptions peuvent permettre des niveaux de grain très fins de la gestion des erreurs pour les utilisateurs de l'API (sujets à la configuration de l'utilisateur ou à des erreurs de données ou à des fichiers introuvables)
Plus d'exceptions vous donnent-elles vraiment un contrôle plus fin du grain? La question est de savoir si le code de capture peut vraiment corriger l'erreur en fonction de l'exception. Je suis sûr qu'il y a des situations comme ça et dans ces cas, vous devriez avoir une autre exception. Mais toutes les exceptions que vous avez énumérées ci-dessus, la seule correction utile est de générer un gros avertissement et d'arrêter l'application.
Plus de classes d'exceptions permettent d'inclure des informations spécifiques aux erreurs dans l'exception, plutôt qu'un simple message de chaîne ou un code d'erreur
C'est une bonne raison d'utiliser des exceptions. Mais les informations doivent être utiles à la personne qui les met en cache. Peuvent-ils utiliser les informations pour effectuer des actions correctives? Si l'objet est interne à votre bibliothèque et ne peut pas être utilisé pour influencer l'une des API, les informations sont inutiles. Vous devez être très précis sur le fait que les informations transmises ont une valeur utile pour la personne qui peut les capturer. La personne qui l'attrape est généralement en dehors de votre API publique, alors personnalisez vos informations afin qu'elles puissent être utilisées avec des éléments de votre API publique.
Si tout ce qu'ils peuvent faire est de consigner l'exception, il est préférable de simplement lancer un message d'erreur plutôt que beaucoup de données. Comme le receveur crée généralement un message d'erreur avec les données. Si vous générez le message d'erreur, il sera cohérent dans tous les capteurs, si vous autorisez le receveur à générer le message d'erreur, vous pourriez obtenir la même erreur différemment selon qui appelle et intercepte.
Moins d'exceptions, mais incorporation d'un code d'erreur pouvant être utilisé comme recherche
Vous devez déterminer la météo pour que le code d'erreur puisse être utilisé de manière significative. Si c'est le cas, vous devriez avoir sa propre exception. Sinon, vos utilisateurs doivent maintenant implémenter des instructions switch à l'intérieur de catch (ce qui va à l'encontre du fait que catch gère automatiquement les choses).
Si ce n'est pas le cas, pourquoi ne pas utiliser un message d'erreur dans l'exception (pas besoin de diviser le code et le message, cela rend la recherche difficile).
Renvoyer des codes d'erreur et des drapeaux directement à partir des fonctions (parfois impossible à partir des threads)
Le retour de codes d'erreur est excellent en interne. Il vous permet de corriger des bugs de temps en temps et vous devez vous assurer de corriger tous les codes d'erreur et de les prendre en compte. Mais les divulguer à travers votre API publique est une mauvaise idée. Le problème est que les programmeurs oublient souvent de vérifier les états d'erreur (au moins à une exception près, une erreur non vérifiée forcera l'application à quitter une erreur non gérée corrompra généralement toutes vos données).
Implémentation d'un système d'événement ou de rappel en cas d'erreur (évite le déroulement de la pile)
Cette méthode est souvent utilisée en conjonction avec un autre mécanisme de gestion des erreurs (pas comme alternative). Pensez à votre programme Windows. Un utilisateur lance une action en sélectionnant un élément de menu. Cela génère une action sur la file d'attente des événements. La file d'attente d'événements affecte finalement un thread pour gérer l'action. Le thread est censé gérer l'action et éventuellement revenir au pool de threads et attendre une autre tâche. Ici, une exception doit être interceptée à la base par le thread chargé de la tâche. Le résultat de la capture de l'exception entraînera généralement la génération d'un événement pour la boucle principale, ce qui entraînera éventuellement l'affichage d'un message d'erreur pour l'utilisateur.
Mais à moins que vous ne puissiez continuer face à l'exception, la pile va se dérouler (pour le thread au moins).