Contexte
Je développe une couche de service API pour un client et on m'a demandé de détecter et de consigner toutes les erreurs au niveau mondial.
Ainsi, alors que quelque chose comme un point de terminaison inconnu (ou une action) est facilement géré en utilisant ELMAH ou en ajoutant quelque chose comme ceci au Global.asax
:
protected void Application_Error()
{
Exception unhandledException = Server.GetLastError();
//do more stuff
}
. . Les erreurs .unhandled qui ne sont pas liées au routage ne sont pas enregistrées. Par exemple:
public class ReportController : ApiController
{
public int test()
{
var foo = Convert.ToInt32("a");//Will throw error but isn't logged!!
return foo;
}
}
J'ai également essayé de définir l' [HandleError]
attribut globalement en enregistrant ce filtre:
filters.Add(new HandleErrorAttribute());
Mais cela n'enregistre pas non plus toutes les erreurs.
Problème / Question
Comment intercepter les erreurs comme celle générée en appelant /test
ci - dessus afin de pouvoir les consigner? Il semble que cette réponse devrait être évidente, mais j'ai essayé tout ce à quoi je pouvais penser jusqu'à présent.
Idéalement, je souhaite ajouter des éléments à la journalisation des erreurs, tels que l'adresse IP de l'utilisateur demandeur, la date, l'heure, etc. Je souhaite également pouvoir envoyer automatiquement un e-mail au personnel de support en cas d'erreur. Tout cela, je peux le faire si seulement je peux intercepter ces erreurs lorsqu'elles se produisent!
RÉSOLU!
Grâce à Darin Dimitrov, dont j'ai accepté la réponse, j'ai compris cela. WebAPI ne gère pas les erreurs de la même manière qu'un contrôleur MVC standard.
Voici ce qui a fonctionné:
1) Ajoutez un filtre personnalisé à votre espace de noms:
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is BusinessException)
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(context.Exception.Message),
ReasonPhrase = "Exception"
});
}
//Log Critical errors
Debug.WriteLine(context.Exception);
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent("An error occurred, please try again or contact the administrator."),
ReasonPhrase = "Critical Exception"
});
}
}
2) Enregistrez maintenant le filtre globalement dans la classe WebApiConfig :
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional });
config.Filters.Add(new ExceptionHandlingAttribute());
}
}
OU vous pouvez ignorer l'enregistrement et simplement décorer un seul contrôleur avec l' [ExceptionHandling]
attribut.
la source
Réponses:
Si votre API Web est hébergée dans une application ASP.NET, l'Application_Error
événement sera appelé pour toutes les exceptions non gérées dans votre code, y compris celle de l'action de test que vous avez affichée. Il vous suffit donc de gérer cette exception dans l'événement Application_Error. Dans l'exemple de code que vous avez montré, vous ne gérez que des exceptions de type,HttpException
ce qui n'est évidemment pas le cas avec leConvert.ToInt32("a")
code. Assurez-vous donc de vous connecter et de gérer toutes les exceptions là-dedans:La gestion des exceptions dans l'API Web peut être effectuée à différents niveaux. Voici une
detailed article
explication des différentes possibilités:attribut de filtre d'exception personnalisé qui pourrait être enregistré comme filtre d'exception global
invocateur d'action personnalisé
la source
Application_Error
événement, cela signifie qu'un autre code la consomme auparavant. Par exemple, vous pourriez avoir des HandleErrorAttributes personnalisés, des modules personnalisés, ... Il existe des millions d'autres endroits où des exceptions pourraient être interceptées et gérées. Mais le meilleur endroit pour le faire est l'événement Application_Error, car c'est là que toutes les exceptions non gérées vont se terminer./test
qu'il arrive , l' exemple n'est pas touché. J'ai mis un point d'arrêt sur la première ligne (Exception unhandledException = . . .
) mais je ne peux pas atteindre ce point d'arrêt dans le/test
scénario. Si je mets une fausse URL, cependant, le point d'arrêt est atteint.Application_Error
événement n'est pas le bon endroit pour gérer les exceptions de l'API Web car il ne sera pas déclenché dans tous les cas. J'ai trouvé un article très détaillé expliquant les différentes possibilités pour y parvenir: weblogs.asp.net/fredriknormen/archive/2012/06/11/…En complément des réponses précédentes.
Hier, l'API Web ASP.NET 2.1 a été officiellement publiée .
Il offre une autre opportunité de gérer les exceptions à l'échelle mondiale.
Les détails sont donnés dans l' exemple .
En bref, vous ajoutez des journaux d'exceptions globaux et / ou un gestionnaire d'exceptions global (un seul).
Vous les ajoutez à la configuration:
Et leur réalisation:
la source
Pourquoi relancer etc? Cela fonctionne et cela rendra le statut de retour du service 500, etc.
la source
avez-vous pensé à faire quelque chose comme un filtre d'action d'erreur de gestion comme
vous pouvez également créer une version personnalisée de
[HandleError]
avec laquelle vous pouvez écrire des informations d'erreur et tous les autres détails à consignerla source
Enveloppez le tout dans un try / catch et enregistrez l'exception non gérée, puis transmettez-la. Sauf s'il existe une meilleure façon intégrée de le faire.
Voici une référence Catch All (géré ou non) Exceptions
(modifier: oh API)
la source