¿Cómo puedo detectar todas las excepciones no controladas que se producen en ASP.NET Web Api para poder registrarlas?
Hasta ahora lo he intentado:
- Crea y registra un
ExceptionHandlingAttribute
- Implementar un
Application_Error
método enGlobal.asax.cs
- Suscribirse a
AppDomain.CurrentDomain.UnhandledException
- Suscribirse a
TaskScheduler.UnobservedTaskException
El ExceptionHandlingAttribute
maneja con éxito las excepciones que se lanzan dentro de los métodos de acción del controlador y los filtros de acción, pero no se manejan otras excepciones, por ejemplo:
- Excepciones lanzadas cuando un
IQueryable
método devuelto por una acción no se ejecuta - Excepciones lanzadas por un controlador de mensajes (es decir
HttpConfiguration.MessageHandlers
) - Excepciones lanzadas al crear una instancia de controlador
Básicamente, si una excepción va a provocar que se devuelva al cliente un error interno del servidor 500, quiero que se registre. La implementación Application_Error
hizo bien este trabajo en Web Forms y MVC: ¿qué puedo usar en Web Api?
c#
asp.net-web-api
unhandled-exception
Joe Daley
fuente
fuente
Respuestas:
Esto ahora es posible con WebAPI 2.1 (consulte Novedades ):
Cree una o más implementaciones de IExceptionLogger. Por ejemplo:
Luego, regístrese con HttpConfiguration de su aplicación, dentro de una devolución de llamada de configuración así:
o directamente:
fuente
La respuesta de Yuval es para personalizar las respuestas a excepciones no controladas capturadas por la API web, no para el registro, como se indica en la página vinculada . Consulte la sección Cuándo usar en la página para obtener más detalles. Siempre se llama al registrador, pero solo se llama al controlador cuando se puede enviar una respuesta. En resumen, use el registrador para iniciar sesión y el controlador para personalizar la respuesta.
Por cierto, estoy usando el ensamblaje v5.2.3 y la
ExceptionHandler
clase no tiene elHandleCore
método. El equivalente, creo, esHandle
. Sin embargo, simplemente la subclasificaciónExceptionHandler
(como en la respuesta de Yuval) no funciona. En mi caso, tengo que implementarIExceptionHandler
lo siguiente.Tenga en cuenta que, a diferencia del registrador, registra su controlador reemplazando el controlador predeterminado, no agregando.
fuente
Para responder a mi propia pregunta, ¡esto no es posible!
El manejo de todas las excepciones que causan errores internos del servidor parece una capacidad básica que debería tener la API web, por lo que solicité a Microsoft un controlador de errores globales para la API web :
https://aspnetwebstack.codeplex.com/workitem/1001
Si está de acuerdo, vaya a ese enlace y vote por él.
Mientras tanto, el excelente artículo Manejo de excepciones de la API web ASP.NET muestra algunas formas diferentes de detectar algunas categorías diferentes de error. Es más complicado de lo que debería ser y no detecta todos los errores del servidor interno, pero es el mejor enfoque disponible en la actualidad.
Actualización: ¡ El manejo de errores globales ahora está implementado y disponible en las compilaciones nocturnas! Se lanzará en ASP.NET MVC v5.1. Así es como funcionará: https://aspnetwebstack.codeplex.com/wikipage?title=Global%20Error%20Handling
fuente
También puede crear un controlador de excepciones global implementando la
IExceptionHandler
interfaz (o heredando laExceptionHandler
clase base). Será el último en ser llamado en la cadena de ejecución, después de todos registradosIExceptionLogger
:Más sobre eso aquí .
fuente
Es posible que tenga bloques try-catch existentes de los que no tenga conocimiento.
Pensé que mi nuevo
global.asax.Application_Error
método no estaba siendo llamado constantemente para excepciones no controladas en nuestro código heredado.Luego encontré algunos bloques try-catch en el medio de la pila de llamadas que llamaba Response.Write en el texto de excepción. Eso fue todo. Volcó el texto en la pantalla y luego mató a la piedra de excepción.
Así que se estaban manejando las excepciones, pero el manejo no estaba haciendo nada útil. Una vez que eliminé esos bloques try-catch, las excepciones se propagaron al método Application_Error como se esperaba.
fuente