sfondo
Sto sviluppando un livello di servizio API per un client e mi è stato richiesto di rilevare e registrare tutti gli errori a livello globale.
Quindi, mentre qualcosa come un endpoint (o un'azione) sconosciuto può essere facilmente gestito utilizzando ELMAH o aggiungendo qualcosa di simile a Global.asax
:
protected void Application_Error()
{
Exception unhandledException = Server.GetLastError();
//do more stuff
}
. . Gli errori .unhandled che non sono correlati al routing non vengono registrati. Per esempio:
public class ReportController : ApiController
{
public int test()
{
var foo = Convert.ToInt32("a");//Will throw error but isn't logged!!
return foo;
}
}
Ho anche provato a impostare l' [HandleError]
attributo a livello globale registrando questo filtro:
filters.Add(new HandleErrorAttribute());
Ma anche questo non registra tutti gli errori.
Problema / Domanda
Come posso intercettare errori come quello generato chiamando /test
sopra in modo da poterli registrare? Sembra che questa risposta dovrebbe essere ovvia, ma finora ho provato tutto ciò a cui riesco a pensare.
Idealmente, voglio aggiungere alcune cose alla registrazione degli errori, come l'indirizzo IP dell'utente richiedente, la data, l'ora e così via. Voglio anche essere in grado di inviare automaticamente un'e-mail allo staff di supporto quando si verifica un errore. Tutto ciò che posso fare se solo riesco a intercettare questi errori quando si verificano!
RISOLTO!
Grazie a Darin Dimitrov, la cui risposta ho accettato, l'ho capito. WebAPI non gestisce gli errori come un normale controller MVC.
Ecco cosa ha funzionato:
1) Aggiungi un filtro personalizzato al tuo spazio dei nomi:
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) Ora registra il filtro a livello globale nella 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());
}
}
O puoi saltare la registrazione e decorare un singolo controller con l' [ExceptionHandling]
attributo.