Générale de la gestion des exceptions en C#
Je suis en cours d'exécution du code par le biais de FxCop et je suis actuellement à la recherche à la compensation de tous les non-rupture des violations.
Le code lui-même a quelques instances de blocs try/catch qui vient d'attraper les exceptions générales;
try
{
//Some code in here that could throw an exception
}
catch(Exception ex)
{
//Exception Thrown ... sort it out!
}
Maintenant, nous savons tous que c'est une mauvaise pratique, mais je pensais que je savais comment le faire correctement - mais FxCop a d'autres idées!
Supposons que le code dans le bloc try pourrait jeter un IO Exception - et seulement un IO exception. Il devrait y avoir rien de mal à cela:
try
{
//Code in here that can only throw an IOException
}
catch (System.IO.IOException ioExp)
{
//Handle the IO exception or throw it
}
catch (System.Exception ex)
{
//Catch otherwise unhandled exception
}
Mais FxCop n'est pas d'accord avec moi ... il a encore des drapeaux cela comme une violation parce que je suis attraper System.Exception
.
Est-ce vraiment une mauvaise pratique ou doit-on/peut-je ignorer cette violation?
L'application est capable d'envoyer des e-mails à notre Helpdesk - ce qui se passait au Développement - de la sorte, nous aurions probablement déclencher l'une de ces avec la trace de la pile.
Êtes-vous absolument sûr que le bloc de code ne peut pas jeter une OutOfMemoryException par exemple, ou une autre erreur fatale..?
Le ci-dessus a été hypothétique - les appels de méthode dans le code réel risque de jeter de l'un des 8 différentes exceptions. Cependant, vous pouvez jamais être sûr qu'ils sont les seuls possibles? D'où la question 😉
OriginalL'auteur DilbertDave | 2009-10-27
Vous devez vous connecter pour publier un commentaire.
Je suis d'accord avec FxCop et la plupart des autres réponses ici: ne pas attraper
System.Exception
jamais, sauf s'il est au plus haut niveau dans votre application pour se connecter inattendu (et donc fatale) exceptions et puis la bombe de l'application. Consultez également cette question, c'est essentiellement à propos de la même chose.Certains, d'autres exceptions pourraient être:
ExpectedExceptionAttribute
.Ce sujet Exception.De données dans le cas général? Ou d'exception personnalisée avec des types de propriétés supplémentaires? Pas un problème. Et vous pouvez aussi attraper une exception au niveau inférieur où vous avez accès à ces données, connectez-vous, si nécessaire, et le paquet de l'exception dans un plus descriptif (personnalisé) type d'exception qu'est le lancer. Pas un problème, par conséquent, à droite?
Vous avez encore à remplir la collecte de Données, et donc vous devez les attraper à l'exception de le faire, et si nous avons encore une autre exception à la ne jamais. Et en voici une autre. Supposons que je suis le traitement d'un grand fichier de commandes indépendantes enregistrements et j'obtiens une exception inattendue du traitement d'un dossier. Dois-je jeter cette exception inattendue jusqu'à "plus haut niveau"? Nan, je l'enregistrer et passer à l'enregistrement suivant, probablement jusqu'à ce que je l'obtenir à la fin du fichier ou le max de mauvais dossiers de permis, selon la première éventualité.
Notez que si vous êtes juste de journalisation et de renvoi, c'est OK. Le point est que votre code est rare de savoir comment poignée une exception non spécifique.
OriginalL'auteur peSHIr
Je suis d'accord avec les autres réponses que
catch (Exception ex)
est très bien si vousIl y a une situation qui me vient à l'esprit là où il pourrait faire sens: Lors de l'écriture sans assistance de code (par exemple, un système de service), il peut faire sens parfait pour garder le programme en cours d'exécution si certains (bien définis) sous-tâche échoue pour quelque raison que ce soit. Bien sûr, les soins doivent être prises pour s'assurer que la raison pour laquelle le problème est connecté et (peut-être) la tâche est essayé à nouveau après un certain temps.
OriginalL'auteur Heinzi
Si vous l'écriture de la bibliothèque(cadre), puis FxCop est de 100% à droite.
Vous intercepter des exceptions - ce que ça veut dire? que vous savez pourquoi ils avaient envoyé. Êtes-vous sûr de connaître toutes les raisons possibles?
Si vous l'écriture de l'application puis de variations possibles. Par exemple, si vous attraper toutes les exceptions non gérées pour la journalisation.
que vous devez les traiter séparément! Une Exception peut-être parce que nom de fichier non valide, l'autre parce que erreur e / s disque. Vous devez répondre séparément sur ce puisqu'il va de communication avec vos utilisateurs. ou tout simplement les ignorer FxCop si il semble ennuyeux pour vous :-).
Mais si je vais à "return false;" à partir de chaque bloc catch, il semble assez inutile. Nous commençons seulement avec des outils d'Analyse de Code comme FxCop et de la nécessité de revoir notre utilisation d'entre eux.
Ouais, comme avant, nous avions TryParse, le moyen le plus facile de dire si une chaîne est un int (facile codewise que c'est) a été de demander à analyser, et retourne true ou d'intercepter l'exception et retourne la valeur false. Le seul vrai problème ici est que l'interception d'une exception pour un cas normal, peut être un peu lent, et si cela se passe dans une boucle intensité de ce qui peut causer votre application à ralentir.
c'est pourquoi TryParse a été ajouté parce que 1)Ce n'EST pas un bon choix de conception lorsque vous attraper une exception juste pour vérifier si vos données dans le bon format ou pas 2) les Exceptions sont lents
OriginalL'auteur Ilya Khaprov
Zone grise...
Dans un monde idéal, vous devriez toujours attraper une exception explicite parce que, en théorie, ceux qui sont le seul type que vous pouvez raisonnablement traiter avec tout le reste devrait influencer certaines haut niveau de gestionnaire.
Le problème est que nous n'avons pas nécessairement vivre dans un monde idéal et peut bien vouloir utiliser un générique gestionnaire d'accumuler plus d'informations sur le générique de l'exception (pour les paramètres, etc) dans l'exception et/ou d'effectuer la journalisation supplémentaire avant de passer à l'exception de retour en haut de l'arborescence et dans tous les cas, au niveau approprié, - à organiser les choses que nos utilisateurs de ne pas voir les exceptions dans l'INTERFACE utilisateur. Le compteur à ce serait de suggérer que lorsque de nouvelles erreurs se produisent à un niveau bas (plutôt que d'arriver dans votre application gestionnaire de niveau), vous pouvez ensuite ajouter une exception spécifique à la manipulation qui peut faire votre capture pour vous - mais il peut y avoir des problèmes de déploiement avec cela comme une solution où, y compris un cas générique en morceaux de code qui sont, pour quelque raison que ce soit, un peu plus sujettes à des exceptions non gérées que l'on voudrait.
Si c'était moi, je serais probablement en considérant le drapeau sur un montage par assemblage de base...
p.s. Je suis en supposant que, à aucun moment, vous disposez d'un gestionnaire de juste avale l'exception et permet à l'application d'effectuer sur.
Euh, j'ai plus catégoriquement pas suggèrent que des exceptions devraient bloquer votre programme. c.f. de niveau supérieur "gestionnaire" - le cas précis que vous soulevez est également un très bon point donc la poursuite de l'observation que vous avez besoin pour traiter de la notion au cas par cas.
Désolé de ne pas lire le reste de votre message. Mon très mauvais.
Plus proche de réponse, je pense, à l'esprit de la langue. J'ai lu des interviews avec Anders, où la question des bagages vs décoché a été posée et sa réponse est que si les développeurs allaient être les erreurs de manipulation au niveau le plus haut de toute façon, la langue ne devrait pas interférer. C'est très bien d'un cas de pragmatisme plus de pureté.
OriginalL'auteur Murph
Vous êtes censés avaler exceptions vous savez comment le gérer. La capture de l'exception et de ne pas jeter ça (que ce soit directement ou enveloppé dans une exception spécifique) signifie que vous connaissez les spécificités de l'exception dans le contexte de l'application. Depuis l'Exception peut être de tout type, il est peu probable que vous savez comment traiter avec elle.
Si vous êtes juste de l'enregistrement de l'exception c'est pas grave, il suffit de vous connecter et de le jeter pour une couche extérieure de la poignée ou le catch.
Généralement, il ne le fera pas beaucoup avec elle, mais une dernière chance pour le gestionnaire global d'exception peut l'attraper, donner de la rétroaction à l'utilisateur et à empêcher l'application à fermer. Ce n'est pas le fardeau d'une bibliothèque de classe pour ce faire, il est de la responsabilité de l'hôte.
Ce qui sonne comme un parfaitement son moyen de traitement d'une exception inattendue. Mais accepteriez-vous il y a des cas où une bibliothèque de classe ne serait pas jeter l'exception inattendue, comme le fichier de commandes indépendantes des enregistrements que j'ai mentionné plus d'une fois déjà sur cette page.
OriginalL'auteur Yann Schwartz
Ce n'FxCopy dire l'infraction est? Si vous voulez juste un journal d'informations concernant une exception alors renvoyer, ce qui est parfaitement valide, bien qu'il existe d'autres moyens de ce qui pourrait être fait. Si vous sur-relancer si, assurez-vous que vous utilisez:
et pas
C'est peut-être le problème?
Oh bon. Aller FxCop ensuite. Quel était le nom de la violation de vous pour la capture du Système.Exception?
La violation en question est DoNotCatchGeneralExceptionTypes : msdn2.microsoft.com/library/ms182137(SV.90).aspx
Ok, il a obtenu maintenant. Ils ne veulent pas vous cacher les détails d'un moment de l'exécution d'exception. Sonne comme quelqu'un qui a un peu de la prostate fixé ici. Considérer le point et si ne s'applique pas, à la charrue. J'ai pris du Système.Exception beaucoup de fois pour des raisons parfaitement valides, et il y a beaucoup de claire le cas où vous auriez besoin.
OriginalL'auteur Swanny
Si le code dans le bloc ne devrait jeter un IOException, alors pourquoi voulez-vous de les attraper Système.Exception?
Ensuite, le degré de conformancy de FxCop lignes directrices que vous voulez atteindre est un choix de la vôtre. Je ne vois rien de mauvais dans la capture de chaque exception au niveau le plus élevé possible et d'enregistrer toutes les informations que vous pouvez, par exemple.
OriginalL'auteur Paolo Tedesco
Vous ne devez attraper les exceptions que vous pouvez faire quelque chose. Sinon, laissez l'exception propager jusqu'à l'appelant ou si, par exemple, dans un Gui application de ces exceptions devraient être traitées par un générique catch tout gestionnaire et puis ouvrez une session. Voir: UnhandledException
Afin de ne pas les attraper, sauf si vous avez l'intention de faire quelque chose avec elle.. il est vrai que ce pourrait être tout simplement l'enregistrement de l'erreur.
Modifier
Aussi regarder Application.ThreadException
Qui, autant que je suis concerné, devrait être la seule exception à la règle de ne jamais attraper
System.Exception
.n'est-ce pas pourquoi vous attribuer un gestionnaire à l'UnhandledException événement?
En fait WinForm global de gestion des exceptions a été améliorée, de sorte que vous pourriez attraper tous d'exception sur le thread GUI à l'écart des autres threads. Pour la plupart des applications, ce fut la même chose. Je ont typiquement une boîte de dialogue qui dit quelque chose le long des lignes de "je suis désolé de la dernière opération n'a pas pu être achevé en raison de l'erreur inattendue suivante:" + ex.Message. Un bouton e-mails que les coordonnées du service d'assistance. Une autre ferme la boîte de dialogue, en donnant à l'utilisateur la possibilité de corriger l'erreur et essayer de nouveau, ou au moins copier les détails qu'ils ont saisi, avant la fermeture. Plutôt que de simplement s'écraser.
Je devrais probablement que c'est un ASP.NET application
OriginalL'auteur Dog Ears