J'ai eu l'habitude d'utiliser une déclaration de capture générale et je gère ces exceptions de manière générale. Est-ce mauvaise pratique? Si oui, comment puis-je savoir quelles exceptions spécifiques pourraient être jetées et lesquelles est-ce que je prends? P>
11 Réponses :
Les méthodes que vous exécutez montreront généralement quelles exceptions peuvent être lancées. Vous pouvez ensuite attraper en conséquence. P>
Si c'est votre propre code, vous pouvez généralement voir ce qui sera lancé ou utiliser les classes sous-jacentes d'exceptions comme guide sur ce que vous aurez besoin de prendre. P>
Je recommande quelques liens: p>
Je crois que la question est de demander comment savoir ce que les classes sous-jacentes vont lancer? par exemple. Java a une clause code> code> qui documente ceci. .NET ne le fait pas.
@spoul - déplacez votre souris sur la classe ou la méthode que vous utilisez et cela montre. Ou utilisez l'explorateur d'objet.
IMHO Ce n'est pas un moyen fiable de la comprendre. Je veux dire, lorsque vous utilisez EF et généré des objets POCO, rien de tout cela n'est documenté. Utiliser des muddies Linq, les eaux encore plus. Qu'en est-il quand j'utilise des conteneurs di et ioc? WHOA, beaucoup de choses à considérer et à peine une chute du seau est documentée de la manière dont vous suggérez!
"Capture en conséquence" est une énoncé jolie large ... Je suggérerais de ne pas attraper et gérer que ces exceptions que vous savez comment gérer correctement. E.G., j'ai une tâche qui fait des appels de base de données. Dans cette tâche, je traite des exceptions de SQL et de réseau provenant de ces appels, car je sais que je peux les récupérer correctement. Je n'attrape rien d'autre dans ce contexte car il n'y a vraiment aucun moyen pour moi de les récupérer. («Récupérer correctement» dans ce cas signifie que je ne corrompre pas l'état d'application ou d'autres ressources.)
Lorsque vous utilisez des méthodes-cadres, vous pouvez vérifier la documentation MSDN. Chaque description de la méthode a une liste d'exceptions potentiellement levées. P>
À titre d'exemple, vérifiez le paragraphe des exceptions sur File.Open () Documentation. P>
Lorsque vous utilisez votre propre méthode, vous devez être conscient des exceptions potentiellement projetées par vos méthodes. P>
Ou dans Visual Studio, survolez la méthode et lisez le commentaire DOC, répertorie également les types d'exception lancés.
Oui, sauf dans quelques cas très spécifiques qui sont mauvaises pratiques. Le seul cas commun que je peux penser à l'accrochage de toutes les exceptions n'est pas une idée moche, c'est lorsque vous enregistrez un message ou une trace de pile juste avant que l'application ne soit sur le point de se déchirer (ou peut-être, vous êtes connecté et repousse). p> li>
attrape uniquement les exceptions que vous savez que vous pouvez gérer. Ni plus ni moins. Si vous ne connaissez pas une exception, vous pouvez être lancé d'une méthode, vous n'allez pas le gérer correctement de toute façon, alors ne l'attrapez pas. Les méthodes et les bibliothèques sont responsables de la documentation des exceptions que vous devriez pouvoir gérer. En outre, ne pas attraper des exceptions indiquant une panne logique, telle que NullReferenceException code> et
argumentException code>. Celles-ci indiquent un véritable bogue dans votre logiciel que vous devriez résoudre, et non quelque chose que vous devez gérer au moment de l'exécution. P> LI>
ol>
Les insectes logiques IMHO doivent également être attrapés. Il vaut mieux échouer et se connecter que d'exploser dans un visage d'utilisateurs / clients. Ces bugs ne devraient pas apparaître bien sûr, mais ils le font toujours et les clients ne se soucient pas du type de problème causé par le crash, ils se rappellent tout simplement que vous avez livré un logiciel de crash. Je suis d'accord avec la plupart de ce que vous avez dit.
@DBemerlin: Les clients détestent le logiciel qui ne fonctionne pas correctement et ils ne savent pas pourquoi. Vous devriez toujours arrêter votre application face à des exceptions non adaptées.
@dbemerlin - Je suis d'accord avec vous du point de vue « les clients voient un bug et ce qui est mauvais. » Toutefois, si les tests ont fait leur travail, ils devraient trouver de nombreux / la plupart de ces bugs logiques et vous pouvez gérer correctement les erreurs (telles que la vérification pour vous assurer un objet est non nul, ou aux entrées validate avant de manipuler un formulaire, etc. ).
Je suis avec Jeff Yates sur celui-ci, 110%. Avec (peut-être?) L'exception du code de réflexion-lourd, je considère que les captures d'exécution d'exceptions à base de logique sont une odeur de code. Vous pouvez et devriez le connecter, bien sûr, mais déchirer l'application.
@Gregd: Je suis en désaccord avec la notion que l'on ne peut pas savoir comment gérer judicieusement des exceptions imprévues. Si la classe easyfoodocument code> a un constructeur qui spécifie un fichier à charger, et il s'appelle à partir de code qui reçoit un nom de fichier à partir d'une boîte de dialogue "Ouvrir un fichier". Il y a d'innombrables choses qui pourraient aller mal pendant la charge, et la bonne façon de gérer 99,44% d'entre eux consiste à informer l'utilisateur que le fichier n'a pas pu être chargé. Même si un programmeur n'a pas anticipé une exception particulière, il faut manipuler de la même manière.
@Gregd: la situation aurait pu être beaucoup mieux si .NET Langues avait permis à Code de savoir quelles exceptions ont été lancées sans les attraper (par exemple, permettant à un enfin code> Block pour avoir une exception
< / Code> Paramètre indiquant quelle exception, le cas échéant, a été lancé dans le
Essayez code> bloc). Il existe de nombreux cas où une exception projetée par une méthode indiquera que certaines structures de données sont corrompues, mais pas si c'est un problème. Si la structure de données est en cours d'introduction à partir d'un fichier fourni à l'utilisateur non valide, le jeter, il résoudra le problème. Si la structure est nécessaire pour fonctionner, cependant, ...
... La corruption est un problème plus important. Avoir un code qui sait sur la corruption invalider expressément les structures de données corrompues i> aiderait à faciliter la manipulation correcte des deux situations; Cela pourrait être facilité à son tour d'avoir un paradigme pour le code pour agir en conséquence d'exceptions sans avoir à prétendre les résoudre.
La question plus grande est si vous devez effectuer une manipulation spécifique des erreurs sur des exceptions spécifiques. Si vous avez juste besoin d'attraper des erreurs qui se produisent, il n'ya rien de mal à faire un bloc d'essai générique / prenant: Cependant, si vous avez besoin de manipulation spécifique à certaines exceptions, vous pouvez Spécifiez plusieurs blocs de capture par un seul essai: p> Si vous ne pouvez pas récupérer à partir d'une exception, ne l'attrapez pas à ce niveau. p> p >
Oui, c'est une mauvaise pratique. Règle de base: "Attrape les exceptions que vous êtes en mesure de répondre aux autres, laissez les autres aller."
try { File.Open(usersChosenFile, FileMode.Open); } catch(FileNotFoundException) { // tell the user the file is gone, give them a chance to respond // this is good } catch(UnauthorizedAccessException) { // this is good too } catch(Exception) { // what did you just catch? Who knows. What if its OutOfMemoryException? // Do you really want to deal with that here? Let this one go by }
imo - n'atteignez aucune exception à moins que vous ne prévoyez d'ajouter de la valeur à celui-ci et / ou il ne peut être traité que dans cette méthode. P>
Veuillez avoir un gestionnaire d'exception commune qui gère toutes les exceptions non traitées. P>
hth. p>
Comme dit Kyle, rendez vos méthodes de petite longueur, essayez uniquement de petites zones. Survolez la souris sur les méthodes que vous appelez - vous devriez obtenir une liste d'exceptions.
Cela n'attribuera pas toutes les exceptions énumérées, mais des exceptions peuvent également être découvertes empiriquement si vous imprimez le type d'exception à l'intérieur de votre Catch (exception E) {...} code>. Ce que vous êtes après est
e.gettype (). FullName code> et
e.stacktrace code> et
e.message code> et
e.innerexception code> ... ou un sous-ensemble de ce que j'ai énuméré. p>
La documentation décrira souvent quelles exceptions une méthode pourrait lancer et les conditions dans lesquelles cela pourrait arriver. Ceci est particulièrement le cas avec la documentation de référence de Microsoft pour le .NET Framework. P>
À mon avis, des exceptions ne doivent être prises que si vous avez une bonne raison de les attraper. Cela signifie généralement que le capture et la manipulation de manière générique est inutile. Exceptions de journalisation (une activité très courante dans un gestionnaire d'exception) ne devrait se produire qu'au bas de la pile d'appels ou chaque fois que vous ne reproduisez pas l'exception (éventuellement enveloppée), qui devrait être rare. Si vous avez une action que vous souhaitez avoir lieu à chaque image de la pile d'appels lorsqu'une exception est bouillonnant, jetez un coup d'œil à des techniques de programmation orientées verso (AOP). P>
Sauf dans des situations rares, je pense généralement aux blocs de capture comme une odeur de code. P>
Prévenir du tout à des exceptions en vérifiant les conditions à l'avance. Par exemple, si la lecture d'un fichier, utilisez des classes dans System.IO pour vérifier si le fichier existe, plutôt que d'utiliser un bloc de capture pour gérer la situation dans laquelle le fichier n'existe pas. P>
Les blocs de capture ne doivent pas faire partie de la logique de votre application. P>
Vous devriez attraper ces exceptions pour lesquelles vous pouvez développer une stratégie raisonnable pour faire face au problème. Il est impossible de saisir une exception s'il n'ya pas de solution raisonnable (réessayant plus tard, en utilisant une technologie / technique différente pour atteindre le même objectif global, informant l'utilisateur que l'objectif ne peut actuellement pas être atteint et ce qu'ils peuvent faire pour remédier à la réparation. la situation em>). P>
exception (pardon): il vaut la peine d'avoir quelque chose au niveau de la très top (E.G. Application.threadException ou AppDomain.unhandleXception) pour tenter de loger ces exceptions que vous n'avez pas manipulées. Si la journalisation échoue, vous êtes condamné quand même. P>
mais avalant aveuglément toutes les exceptions (en particulier à un niveau bas) peut conduire à des sessions de débogage / diagnostic très frustrantes. P>
Vous devez prendre une décision de conception quant à la question de savoir si vous avez vraiment besoin d'attraper toutes les exceptions à ce stade du code. Je connais deux conditions où attraper L'inconvénient d'attraper toutes les exceptions est masquant un message d'erreur potentiellement utile et en ignorant, causant des effets secondaires inattendus dans votre application. P> exception code> a du sens: p>
Je souhaite qu'il y ait une "mode anale" pour VS2008 / 10 qui vous obligerait à gérer toutes les exceptions.
@Hamish: Vous pouvez essayer de faire une extension. Des exceptions non cochées constituaient un choix de conception très délibéré, mais basé sur des leçons tirées de Java.
@Greg D, comment puis-je continuer à la mettre en œuvre?
@Hamish Grubijan, je suggère de commencer au début et de partir de là: Microsoft.com/downloads/...