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.