Moyen facile d'attraper toutes les exceptions non gérées dans C#.NET
J'ai un site web construit en C#.NET qui tend à produire un assez constant flux de SQL délais d'attente à partir de différentes commandes de l'utilisateur et je veux facilement de la pop un peu de code pour attraper toutes les exceptions non gérées et de les envoyer à quelque chose qui peut se connecter et afficher un message amical à l'utilisateur.
Comment puis-je, par un minimum d'effort, attraper toutes les exceptions non gérées?
cette question semble dire que c'est impossible, mais cela ne fait pas de sens pour moi (et c'est sur .NET 1.1 dans les applications windows):
- N'est-ce pas que le fait de traiter les symptômes et non la cause? c'est à dire ne devriez-vous pas être à la recherche à la cause de la SQL délais d'attente en exécutant une trace du générateur de profils SQL sur le serveur de base de données?
- Je pense que vous avez besoin de clarifier ce que vous entendez par "attraper": Comme dans try..catch où vous pouvez gérer l'exception, ou si vous voulez simplement être informé d'une exception non gérée s'est produite, et le journal où/quand (par exemple ELMAH)
- Pouvez-vous marquer l'une des réponses que la bonne?
Vous devez vous connecter pour publier un commentaire.
Toutes les exceptions non gérées enfin passé à travers Application_Error mondiale.asax. Ainsi, pour donner générale message de l'exception ou de faire des opérations forestières, voir Application_Error.
<customErrors mode="Off"/>
dans le web.config. Sans cette entrée, il ne fonctionnait pas sur le serveur de production pour moi.Si vous avez besoin pour attraper les exeptions dans tous les threads la meilleure approche est de mettre en œuvre UnhandledExceptionModule et l'ajouter à votre application look ici
pour un exemple
Utiliser la méthode Application_Error dans votre Global.asax fichier. À l'intérieur de votre Application_Error méthode de la mise en œuvre du Serveur d'appel.GetLastError(), enregistrer les détails de l'exception retournée par le Serveur.GetLastError() comme vous le désirez.
par exemple
Ne payez pas trop d'attention à la log4net trucs, Serveur.GetLastError() est le plus utile bits, enregistrer les détails toutefois vous préférez.
La ELMAH projet sons vaut la peine d'essayer, la liste de ses caractéristiques comprennent:
Plus sur l'utilisation de ELMAH de dotnetslackers
Vous pouvez vous abonner à la
AppDomain.CurrentDomain.UnhandledException
événement.Il est probablement important de noter que vous êtes pas censé pour attraper les exceptions non gérées. Si vous rencontrez SQL problèmes de délai d'attente, vous devez attraper ces.
throw
déclaration?Voulez-vous dire de le manipuler dans toutes les discussions, y compris celles créées par la troisième partie du code? Dans "connu" fils juste attraper
Exception
en haut de la pile.Je vous recommande de regarder log4net et de voir si c'est adapté pour l'enregistrement de la partie de la question.
Si vous l'utilisez .net framework 2.0, j'ai utiliser le construit en Surveillance de la Santé des services. Il y a un bel article décrivant cette méthode ici: http://aspnet.4guysfromrolla.com/articles/031407-1.aspx
Si vous êtes coincé avec le 1.0 cadre, je voudrais utiliser ELMAH:
http://msdn.microsoft.com/en-us/library/aa479332.aspx
espère que cette aide
Il y a 2 parties à ce problème, la manipulation & identifier.
Identifier
C'est ce que vous faites lorsque l'exception est enfin attrapé, pas nécessairement là où il est jeté. Donc l'exception à cette étape doit avoir suffisamment d'informations de contexte pour que vous idenitfy quel était le problème
Manipulation
Pour la manipulation, vous pouvez
a) ajouter un HttpModeule. Voir
http://www.eggheadcafe.com/articles/20060305.asp
Je suggère cette approche uniquement lorsqu'il n'y a absolument pas de contexte informaatn disponible, et il peut être issuus avec IIS/aspnet, bref pour des situations de catastrophe
b) Créer une classe abstraite appelée AbstractBasePage qui dérive de la classe de la Page et d'avoir tous vos codebehind les classes dérivent de AbstractBasePage
La AbstractBasePage pouvons mettre en œuvre cette Page.Erreur de déléguer afin que toutes les exceptions qui s'infiltre par le biais de la n-tier architecture peut être pris ici(et éventuellement connecté)
Je suggère cette cause la nature des exceptions dont vous parlez (SQlException) il y a suffisamment d'informations de contexte pour vous d'identifier qu'il a un délai d'attente et prendre des mesures possibles. Cette action pourrait inclure de rediriger l'utilisateur vers une page d'erreur personnalisée avec le message approprié pour chaque type d'exception (Sql, webservices, appel asynchrone délais d'attente, etc).
Merci
RVZ
Une courte réponse est à utiliser (Anonyme) délégué méthodes de traitement des communes code lorsque le délégué est appelé.
Fond: Si vous avez ciblé les points faibles, ou qui ont des passe-partout de code de gestion d'erreur, vous devez appliquer universellement à une classe particulière de problème, et vous ne voulez pas écrire la même try..catch pour chaque invocation de l'emplacement, (comme la mise à jour d'un contrôle spécifique sur chaque page, etc).
Étude de cas: Une douleur au point des formulaires web et l'enregistrement des données dans la base de données. Nous avons un contrôle qui affiche les enregistré statut de l'utilisateur, et nous avons voulu en commun code de gestion d'erreur ainsi que le bon de s'afficher sans copier-coller de réutilisation dans chaque page. Aussi, chaque page a sa propre chose à sa façon, de sorte que la seule vraiment partie du code a été l'erreur de manipulation et d'affichage.
Maintenant, avant d'être claqué, ce n'est pas pour le remplacement d'une couche d'accès aux données et le code d'accès aux données. C'est toujours à supposer qu'elle existe, de la bonne n de la couche de séparation, etc. Ce code est l'INTERFACE utilisateur-couche spécifique afin de nous permettre d'écrire propre code de l'INTERFACE utilisateur et de ne pas nous répéter. Nous sommes de grands croyants dans les pas d'annulation des exceptions, mais certaines exceptions ne doivent pas nécessiter l'utilisateur d'obtenir une page d'erreur générique et de perdre leur travail. Il y aura sql délais d'attente, les serveurs sont en panne, les blocages, etc.
Une Solution: La façon dont nous l'avons fait a été de passer un délégué anonyme à une méthode sur un contrôle personnalisé et essentiellement injecter le bloc d'essai à l'aide de délégués anonymes.
La SaveControl a lui-même la méthode comme:
Erreurs de délai d'attente généralement se produire si vous forcez pas la fermeture de votre sqlconnections.
donc si vous aviez un
Si quelque chose va mal avec cette ExecuteReader votre connexion ne sera pas fermé. Toujours ajouter un bloc finally.
using
de blocs, qui sont dans le bon sens pour éviter le problème dont vous parlez.using
bloque à chaque fois que vous créez une instance de classe implémentant IDisposable est la meilleure façon de prévenir ces fuites de ressource. Et c'est plus important sur un site comme celui-ci, où moins de développeurs expérimentés peuvent copier et coller le code "exemples" de ceux qui devraient savoir mieux. Laissez-moi savoir si vous voulez de moi, soit pour nettoyer le vôtre, ou à créer une réponse distincte, propre, mais en se référant à la vôtre.C'est une vieille question, mais la meilleure méthode (pour moi) n'est pas répertorié ici. Nous sommes donc ici:
ExceptionFilterAttribute est agréable et facile solution pour moi. Source: http://weblogs.asp.net/fredriknormen/asp-net-web-api-exception-handling.
Et de l'attacher à f.e. HomeController: