Contexte
Je suis en train de développer une couche de service API pour un client et on m'a demandé d'attraper et d'enregistrer toutes les erreurs de manière globale.
Ainsi, alors que quelque chose comme un point de terminaison (ou une action) inconnu(e) est facilement géré en utilisant ELMAH ou en ajoutant quelque chose comme ceci à la section Global.asax
:
protected void Application_Error()
{
Exception unhandledException = Server.GetLastError();
//do more stuff
}
. . les erreurs non gérées 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 le [HandleError]
de manière globale en enregistrant ce filtre :
filters.Add(new HandleErrorAttribute());
Mais cela ne permet pas non plus d'enregistrer toutes les erreurs.
Problème/Question
Comment puis-je intercepter les erreurs comme celle générée par l'appel de la fonction /test
ci-dessus pour que je puisse les enregistrer ? Il semble que cette réponse devrait être évidente, mais j'ai essayé tout ce à quoi j'ai pensé jusqu'à présent.
Idéalement, je voudrais ajouter certains éléments à la journalisation des erreurs, comme l'adresse IP de l'utilisateur demandeur, la date, l'heure, etc. Je voudrais également pouvoir envoyer automatiquement un courriel au personnel d'assistance lorsqu'une erreur est rencontrée. Tout cela, je peux le faire si seulement je peux intercepter ces erreurs quand elles se produisent !
RÉSOLU !
Grâce à Darin Dimitrov, dont j'ai accepté la réponse, j'ai trouvé la solution. WebAPI fait no traiter les erreurs de la même manière qu'un contrôleur MVC ordinaire.
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) Maintenant, enregistrez le filtre de manière globale dans le fichier WebApiConfig classe :
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 décorer un seul contrôleur avec l'attribut [ExceptionHandling]
attribut.
0 votes
J'ai le même problème. Les exceptions non gérées sont prises en compte dans l'attribut de filtre d'exception, mais lorsque je lance une nouvelle exception, elle n'est pas prise en compte dans l'attribut de filtre d'exception.
1 votes
Des appels de contrôleur d'api inconnus comme monhost/api/undefinedapicontroller Les erreurs ne sont toujours pas capturées. Le code du filtre Application_error et Exception n'est pas exécuté. Comment les attraper également ?
1 votes
La gestion des erreurs globales a été ajoutée à la WebAPI v2.1. Voir ma réponse ici : stackoverflow.com/questions/17449400/
1 votes
Cela ne permettra pas de détecter les erreurs dans certaines circonstances, comme "ressource non trouvée", ou les erreurs dans le constructeur d'un contrôleur. Voir ici : aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/Elmah/
0 votes
Bonjour, @Matt. Vous avez écrit la réponse comme faisant partie de la question, mais ce n'est pas une bonne pratique en SO. Ici, les réponses doivent être séparées de la question. Pourriez-vous rédiger cette réponse séparément (vous pouvez utiliser le bouton bleu "Répondre à votre propre question" en bas de la page).