Comment intercepter toutes les exceptions non gérées qui se produisent dans l'API Web ASP.NET afin de pouvoir les consigner?
Jusqu'à présent, j'ai essayé:
- Créer et enregistrer un
ExceptionHandlingAttribute
- Implémenter une
Application_Error
méthode dansGlobal.asax.cs
- S'abonner à
AppDomain.CurrentDomain.UnhandledException
- S'abonner à
TaskScheduler.UnobservedTaskException
Le ExceptionHandlingAttribute
gère avec succès les exceptions qui sont levées dans les méthodes d'action du contrôleur et les filtres d'action, mais les autres exceptions ne sont pas gérées, par exemple:
- Exceptions levées lorsqu'un
IQueryable
retourné par une méthode d'action échoue à s'exécuter - Exceptions levées par un gestionnaire de messages (ie
HttpConfiguration.MessageHandlers
) - Exceptions levées lors de la création d'une instance de contrôleur
Fondamentalement, si une exception va provoquer le renvoi d'une erreur de serveur interne 500 au client, je veux qu'elle soit enregistrée. La mise en œuvre Application_Error
a bien fonctionné dans Web Forms et MVC - que puis-je utiliser dans Web Api?
c#
asp.net-web-api
unhandled-exception
Joe Daley
la source
la source
Réponses:
Ceci est maintenant possible avec WebAPI 2.1 (voir Quoi de neuf ):
Créez une ou plusieurs implémentations de IExceptionLogger. Par exemple:
Ensuite, inscrivez-vous avec HttpConfiguration de votre application, dans un rappel de configuration comme ceci:
ou directement:
la source
La réponse de Yuval est de personnaliser les réponses aux exceptions non gérées capturées par l'API Web, pas pour la journalisation, comme indiqué sur la page liée . Reportez-vous à la section Quand utiliser sur la page pour plus de détails. L'enregistreur est toujours appelé mais le gestionnaire n'est appelé que lorsqu'une réponse peut être envoyée. En bref, utilisez le logger pour enregistrer et le gestionnaire pour personnaliser la réponse.
Au fait, j'utilise l'assembly v5.2.3 et la
ExceptionHandler
classe n'a pas laHandleCore
méthode. L'équivalent, je pense, estHandle
. Cependant, le simple sous-classementExceptionHandler
(comme dans la réponse de Yuval) ne fonctionne pas. Dans mon cas, je dois mettreIExceptionHandler
en œuvre comme suit.Notez que, contrairement à l'enregistreur, vous enregistrez votre gestionnaire en remplaçant le gestionnaire par défaut et non en ajoutant.
la source
Pour répondre à ma propre question, ce n'est pas possible!
La gestion de toutes les exceptions qui provoquent des erreurs de serveur internes semble être une capacité de base que l'API Web devrait avoir, j'ai donc demandé à Microsoft un gestionnaire d'erreurs global pour l'API Web :
https://aspnetwebstack.codeplex.com/workitem/1001
Si vous êtes d'accord, accédez à ce lien et votez pour lui!
En attendant, l'excellent article Gestion des exceptions de l'API Web ASP.NET montre différentes façons de détecter quelques catégories d'erreur différentes. C'est plus compliqué qu'il ne devrait l'être, et cela ne détecte pas toutes les erreurs de serveur internes, mais c'est la meilleure approche disponible aujourd'hui.
Mise à jour: la gestion globale des erreurs est désormais implémentée et disponible dans les versions nocturnes! Il sera publié dans ASP.NET MVC v5.1. Voici comment cela fonctionnera: https://aspnetwebstack.codeplex.com/wikipage?title=Global%20Error%20Handling
la source
Vous pouvez également créer un gestionnaire d'exceptions global en implémentant l'
IExceptionHandler
interface (ou en héritant de laExceptionHandler
classe de base). Ce sera le dernier à être appelé dans la chaîne d'exécution, après tout enregistréIExceptionLogger
:Plus à ce sujet ici .
la source
Vous pouvez avoir des blocs try-catch existants dont vous n'êtes pas au courant.
Je pensais que ma nouvelle
global.asax.Application_Error
méthode n'était pas systématiquement appelée pour des exceptions non gérées dans notre ancien code.Ensuite, j'ai trouvé quelques blocs try-catch au milieu de la pile d'appels qui ont appelé Response.Write sur le texte d'exception. C'était ça. J'ai vidé le texte sur l'écran, puis tué la pierre d'exception.
Les exceptions étaient donc gérées, mais la manipulation ne faisait rien d'utile. Une fois que j'ai supprimé ces blocs try-catch, les exceptions se sont propagées à la méthode Application_Error comme prévu.
la source