Je gère du code via FXCop et je suis actuellement en train d'examiner toutes les violations non rompues.
Le code lui-même a quelques cas d'essais / attraper des blocs qui attrapent juste des exceptions générales; p> Nous savons tous que c'est une mauvaise pratique mais je pensais que je savais que je savais que je savais que je savais que je savais que je savais que je sacheais Comment le faire correctement - mais FXCop a d'autres idées! p> Supposons que le code dans le bloc d'essai puisse lancer une exception IO - et seule une exception IO. Il ne devrait y avoir rien de mal à faire cela: p> mais FXCOP n'est pas d'accord avec moi ... il signe toujours cela comme une violation parce que j'attrape est-ce vraiment mauvaise pratique ou si je devrais / puis-je ignorer en toute sécurité cette violation? P> P> System.Exception code>. P>
8 Réponses :
Si vous écrivez la bibliothèque (cadre), alors FXCOP est 100% à droite. p>
Vous attrapez des exceptions - ce que c'est méchant? que vous savez pourquoi ils ont jeté. Êtes-vous sûr de connaître toutes les raisons possibles? P>
Si vous écrivez juste une application, des variations possibles. Par exemple, si vous attrapez toutes les exceptions non manquées pour la journalisation. P>
Je suis sûr que vous ne pouvez jamais connaître toutes les raisons mais que vous recherchez les appels de méthode dans le bloc d'essai, je sais que la pièce de code actuelle pourrait lancer au moins 8 types d'exception différents.
que vous devez les gérer tous séparément! Une exception peut être parce que le nom de fichier non valide, un autre parce que l'erreur IO du disque. Vous devriez répondre séparément à ce sujet puisqu'il dirigera la communication avec vos utilisateurs. Ou ignorer simplement FXCop si cela semble ennuyeux pour vous :-).
Mais si je vais juste "retourner faux; ' de chaque bloc de capture, il semble assez inutile. Nous ne faisons que commencer par les outils d'analyse de code tels que FXCop et doivent revoir notre utilisation d'eux.
Ouais, comme avant que nous avions une trypairse, le seul moyen facile de dire si une ficelle était une chaîne (facilité de code de code) consistait à appeler analyser, et à retourner vrai ou à attirer l'exception et à renvoyer false. Le seul problème réel ici est que la capture d'une exception pour un cas normal peut être un peu lente et si cela se produit de manière intensive en boucle, cela peut entraîner une ralentir votre application.
@Swny c'est pourquoi Tryparse a été ajouté parce que 1) Ce n'est pas un bon choix de conception lorsque vous attrapez une exception juste pour vérifier si vos données au format droit ou non 2) sont lentes.
Ouais, mais pas si lent. Pour la validation standard de saisie de données, il a été parfaitement validé. Personne ne m'a jamais plaint pour moi que "Gee Wiz, que le temps de réponse est de 1 milli deuxièmement trop lent. Si devait analyser un million ou plus de valeurs et il y avait de bonnes chances qu'ils avaient tort de réexaminer (Mabye vérifier la longueur et la Mélange de caractères en premier). Ces jours-ci, j'utilise Tryparse. N'oubliez pas que la violation consiste à ne pas essayer de masquer des erreurs de temps d'exécution inattendues, pas sur la performance. Et pour les bibliothèques de classe, oui, je pourrais simplement vouloir me connecter toutes les exceptions avec dire, les valeurs de paramètre qui l'ont causée.
Que dit FXCopopy que la violation spécifique est-elle? Si vous souhaitez simplement enregistrer des informations sur une exception, c'est à ce moment-là que cela est parfaitement valide, bien que cela puisse être fait. Si vous le renoncez cependant, assurez-vous d'utiliser simplement: et non p> peut-être que c'est peut-être le problème? p> p>
Il y a quelques cas de cela, mais qui est signalé comme une violation de RethowtoPreServestackDétails.
Oh super. Go FXCop alors. Quel était le nom de la violation que vous receviez pour capturer System.Exception?
La violation en question est DonotcatchGeneralExceptionTypes: MSDN2.microsoft.com/Library/ms182137 ( Vs.90) .aspx
Ok, je l'ai maintenant. Ils ne veulent pas que vous masquiez des détails d'une exception de temps d'exécution. On dirait que quelqu'un a une petite prostate fixée ici. Considérons le point et si cela ne s'applique pas, labourez. J'ai attrapé System.Exception Beaucoup de fois pour des raisons parfaitement valables, et il y a beaucoup de cas clairs dans lesquels vous auriez besoin.
Si le code dans le bloc ne doit lancer qu'une idée IoException, alors pourquoi voulez-vous attraper System.Exception aussi? p>
Ensuite, le degré de conformité aux directives FXCOP que vous souhaitez réaliser est un choix de votre choix. Je ne verrais rien de mal à attraper toutes les exceptions au niveau le plus élevé possible et à enregistrer toutes les informations que vous pouvez, par exemple. P>
Vous ne devez attraper que des exceptions que vous pouvez faire quelque chose. Sinon, laissez l'exception se propager jusqu'à l'appelant ou si, par exemple, dans une application d'interface graphique, les exceptions doivent être traitées par une prise générique de tout gestionnaire, puis connectée. Voir: non gourde) Alors ne attrapez pas si vous aviez l'intention de faire quelque chose avec elle. Certes, cela pourrait simplement enregistrer l'erreur. P>
Vrai - mais sûrement sauf si vous attrapez toutes les exceptions à un moment donné, cela va arriver à l'interface utilisateur comme une exception non gérée.
@DilbertDave: ce qui est en ce qui me concerne devrait être la seule exception à la règle de ne jamais attraper system.exception code>.
@DilbertDave n'est-ce pas pourquoi vous attribuez un gestionnaire à l'événement non aménagé?
En réalité, Winform Global Exception Maniping a été amélioré afin que vous puissiez prendre toute exception sur le fil d'interface graphique séparé des autres threads. Pour la plupart des applications, c'était la même chose. J'ai généralement une boîte de dialogue commune qui dit quelque chose dans le sens de "Je suis désolé, la dernière opération n'a pas pu être complétée en raison de l'erreur inattendue suivante:" + ex.message. Un bouton emaille les détails au bureau de service. Un autre ferme la boîte de dialogue, donnant à l'utilisateur une chance de corriger l'erreur et de réessayer ou d'essayer au moins copier les détails qu'ils ont entrés avant la fermeture. Plutôt que de se bloquer.
Je devrais probablement souligner que ceci est une application ASP.NET
Vous êtes censé avaler des exceptions, vous savez comment gérer. Attraper l'exception et ne pas le jeter (directement ou enveloppé dans une exception spécifique) signifie que vous connaissez les détails de l'exception dans le contexte de l'application. Depuis que l'exception peut être quelque chose, il est peu probable que vous sachiez comment y faire face. P>
Si vous enregistrez simplement l'exception, il ne s'agit pas d'une grosse affaire, jetez-la et jetez-la pour une couche externe à manipuler ou à attraper. p>
Sauf bien sûr, que fait la couche externe à l'exception si elle ne l'attendait pas?
Habituellement, cela ne fera pas grand chose avec elle, mais un gestionnaire d'exception global de dernière chance peut l'attraper, fournir des commentaires à l'utilisateur et empêcher l'application de fermer. Ce n'est pas le fardeau d'une bibliothèque de classe de faire cela, c'est la responsabilité de l'hôte.
Ce qui semble être un moyen parfaitement solide de manipuler une exception inattendue. Mais accepteriez-vous qu'il y a des cas où une bibliothèque de classe ne jetterait pas l'exception inattendue, comme le fichier de lots d'enregistrements indépendants que j'ai mentionnés plus d'une fois sur cette page.
zone grise ... p>
Dans un monde idéal, vous attrapiez toujours une exception explicite car, en théorie, ce sont la seule sorte que vous puissiez gérer judicieusement - tout ce qui devrait être percolaire à un gestionnaire de haut niveau. P>
Le problème est que nous ne vivons pas nécessairement dans un monde idéal et que vous souhaitiez bien utiliser un gestionnaire générique pour accumuler des informations supplémentaires sur l'exception générique (paramètres, etc.) à l'exception et / ou pour effectuer une journalisation supplémentaire avant de passer la Exception sauvegardez l'arbre et dans tous les cas - au niveau approprié - pour organiser ainsi des choses que nos utilisateurs finaux ne voient pas d'exceptions crues dans l'interface utilisateur. Le comptoir à ce sujet serait de suggérer que lorsque de nouvelles erreurs se produisent à un niveau bas (plutôt que d'arriver à votre gestionnaire de niveau d'application), vous ajoutez ensuite une manipulation spécifique d'exception 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 dans des bits de code qui sont, pour une raison quelconque, un peu plus sujettes à des exceptions non endommagées que l'on pourrait aimer. P>
Si c'était moi, je voudrais probablement envisager le drapeau sur un assemblage par ensemble de montage ... P>
P.s. Je suppose qu'en notamment que vous avez un gestionnaire qui avale l'exception et permet à l'application de continuer. P>
Attendez. Vous ne saisissez que les exceptions que vous attendez. Des exceptions si inattendues sont-elles laissées pour cracer votre programme? Ce n'est pas ce que j'appellerais une solution professionnelle. Regardez la gestion des exception générale WinForms qui a été introduite pour WinForms (1.1 ou 2.0). Et si j'avais besoin de traiter 1 million d'enregistrements indépendants dans un fichier, je préférerais attraper l'exception inattendue, enregistrez l'erreur sur un journal avec le numéro d'enregistrement, puis passez à l'enregistrement suivant, éventuellement avec un numéro de dossier maximal maximum autorisé.
Erm, j'ai le plus insisté pas i> suggère que des exceptions inattendues devraient planter votre programme. c.f. "Hangler de haut niveau" - Le cas spécifique que vous soulevez est également un très bon point d'où l'observation supplémentaire dont vous avez besoin pour faire face à la notion au cas par cas.
La réponse la plus proche, je pense, à l'esprit de la langue. J'ai lu entretiens avec Anders où la question de vérification de VS non cochée a été soulevée et que sa réponse est que si les développeurs allaient manipuler des erreurs au niveau supérieur de toute façon, la langue ne doit pas interférer. C'est vraiment un cas de pragmatisme sur la pureté.
Je suis d'accord avec FXCop et la plupart des autres réponses ici: N'attribuez pas Certaines autres exceptions valides peuvent être: p>
system.Exception code> jamais em>, sauf si elle est au plus haut niveau de votre application pour vous connecter. Exceptions inattendues (et donc fatales), puis bombardez l'application. Découvrez également cette question qui est fondamentalement à peu près le même chose. p>
attenduExceptionTatribute code>. Li>
Et si vous souhaitez vous connecter à l'exception, certaines valeurs des paramètres de la méthode de niveau inférieur, cela se produit? Ne peut pas faire cela à partir du "plus haut niveau de votre application".
@Swanny: Qu'en est-il de l'exception.Data pour cela dans le cas général? Ou types d'exception personnalisés avec des propriétés supplémentaires? Pas de problème. Et vous pouvez également attraper une exception au niveau inférieur où vous avez accès à ces données, le loger si nécessaire et emballer l'exception dans un type d'exception plus descriptif (personnalisé) à lancer. Pas un problème, donc, non?
Vous devez toujours renoncer à la collecte de données et vous devez donc attraper l'exception pour le faire, et nous avons donc une autre exception à ne pas jamais. Et voici un autre. Supposons que je traite un grand fichier de commandes d'enregistrements indépendants et que j'obtiens une exception inattendue, un enregistrement. Est-ce que je jette cette exception inattendue jusqu'à "le plus haut niveau"? Nope, je le connecte et passez à l'enregistrement suivant, probablement jusqu'à ce que je reçoive la fin du fichier ou les bad dossiers maximaux autorisés, selon la première éventualité.
Notez que si vous vous enregistrez et retiré, c'est bon. Le point est que votre code est peu susceptible de savoir comment gérer B> une exception non spécifique.
Je suis d'accord avec les autres réponses que Il y a une situation supplémentaire qui me vient à l'esprit où elle pourrait avoir du sens: lors de la rédaction de code sans assistance (par exemple, un service système), il peut avoir un sens idéal pour garder le programme en cours d'exécution em> si certains ( Une sous-tâche bien définie) échoue à quelque raison que ce soit. Bien sûr, il faut veiller à ce que la raison du problème soit connectée et (peut-être) la tâche est à nouveau essayée après un certain temps. P> attrape (excepte EX) code> est bien si vous p>
Cela dépend ... Que faites-vous dans "// attrape une exception autrement non gérée"?
L'application est capable d'envoyer des courriels à notre Helpdesk - qui se transmettent au développement - nous en déclenchions donc probablement l'un d'entre eux avec la trace de la pile.
Êtes-vous absolument sûr que le bloc de code ne peut pas lancer une exception exceptionnelle exceptionnelle, ou une autre erreur fatale ..?
Ce qui précède était hypothétique - la méthode appelle dans le code réel pourrait lancer l'une des 8 exceptions différentes. Cependant, pouvez-vous jamais être sûr qu'ils sont les seuls possibles? D'où la question ;-)