2010-08-09 17 views

Respuesta

2

Además del Exception? Solo agregaría una llamada a mi módulo de registro en mi bloque catch.

Algo así como:

catch(YourException ex) 
{ 
    LogMyException(ex, [otherParamsYouNeed]); 
    //Other Exception Handling 
} 

Si desea registrar el estado de algo independientemente del éxito o el fracaso, utilice finally{}

1

En WinForms tienes el evento Application.ThreadException y más general está el evento AppDomain.CurrentDomain.UnhandledException.

Pero tenga en cuenta que después de registrar estas excepciones, se recomienda cerrar la aplicación. Es posible que ya no esté en un estado estable.

+0

+1, Estos controladores son el mejor lugar para registrar las excepciones no controladas que dará lugar a la terminación de la aplicación. Creo que esto es mucho más limpio que 'log and rethrow' más cerca del punto de la falla, ya que las clases .Exception ya conservan información contextual como StackTrace. –

1

La clase AppDomain tiene un evento UnhandledException, pero no creo que se puede suscribir a cualquier excepción de tiro.

6

Sí - no es el UnhandledException evento en el AppDomain objeto:

AppDomain.CurrentDomain.UnhandledException += YourHandler 

FYI: Sólo debe utilizar estos controladores como último recurso - que es mucho mejor para atrapar excepciones en un bloque trycatch, aunque esto no siempre es posible (por ejemplo, cuando el código de un tercero inicia nuevos hilos)

Además, este evento solo se disparará cuando una excepción sea no administrada - a mi conocimiento no hay forma de ser notificado de eventos capturados de esta manera sin asociar un depurador al proceso.

+0

+1 para "solo debe usar estos controladores como último recurso", lo utilizo para registrar la excepción, informar al usuario y reiniciar solo la aplicación.De lo contrario, puede entrar en todo tipo de problemas. –

+0

No está claro en la documentación, pero no parece que suscribirse a este evento le brinde la oportunidad de bloquear el cierre de AppDomain. –

0

En ASP.NET, las excepciones no controladas pueden capturarse en el nivel de página manejando el evento Page_Error, o en el nivel de aplicación (en global.asax, o en una implementación de IHttpModule) manejando eventos de Error de aplicación. Estos eventos no le dan la excepción real, por lo que tendrá que llamar al servidor para obtener la excepción:

Exception ex = HttpContext.Current.Server.GetLastError(); 
4

Usted debe echar un vistazo a hacer un poco de programación orientada a aspectos con PostSharp, se puede escribir una simple atributo de registro y aplicarlo a su conjunto completo.

Todo lo que necesita es algo como esto:

[Serializable] 
public class LogAttribute : OnMethodInvocationAspect 
{ 
    public override void OnInvocation(MethodInvocationEventArgs eventArgs) 
    { 
     try 
     { 
     eventArgs.Proceed(); 
     } 
     catch(Exception ex) 
     { 
     // log exception here 
     } 
    } 
} 

y aplicarlo a su montaje:

[assembly: Log] 
public class ... 

No es del gusto de todos, pero he encontrado que es un lugar muy limpio, Manera ordenada de evitar hacer un montón de código repetitivo en mis clases y me libera para trabajar en funcionalidades más relacionadas con el proyecto en sí.

Actualización: como señaló Kugel en el comentario, esto le ayudará a rastrear y registrar cualquier excepción lanzada durante la ejecución del método, pero si desea registrar el estado interno del método, necesitará hacer un poco más de trabajo que esto.

Por ejemplo, es posible que aún necesite probar/atrapar bloques dentro de su método que podría utilizar para capturar excepciones que interesan a su clase y tal vez incluso envolverlas en un objeto de excepción personalizado para que pueda comenzar a agregar información más útil como un código de error, etc. Hasta que su excepción personalizada tenga un mecanismo adecuado para configurar su propiedad 'Mensaje', por ej.

public class DictionaryKeyNotValidException() : Exception 
{ 
    public DictionaryKeyNotValidException(string key) 
     : base(GetMessage(key)) 
    { 
    } 

    public ErrorEnum ErrorCode { get { return ErrorEnum.InvalidDictionaryKey; } } 

    private string GetMessage(string key) 
    { 
     return string.Format("ERROR {0} : Invalid dictionary key encountered {1}", 
          ErrorCode.GetHashCode(), key); 
    } 
} 

continuación, en el atributo de registro, siempre que estés utilizando Log4net, se puede iniciar el registro de la información más útil:

catch (Exception ex) 
{ 
    // log error 
    log.Error(ex); 

    // handle exception, rethrow, etc. 
    ... 
} 

Lo sentimos, este se está convirtiendo en un poco largo aliento ..

+0

Aún así, si desea registrar un estado dentro de un método, esto no lo ayudará. – Kugel

+1

Solo asegúrese de incluir 'throw;' después del registro. –

0

Para extienda la respuesta dada por theburningmonk, también podría intentar usar log4PostSharp. Este es un código preconstruido que usa PostSharp para insertar el código de registro que funciona con el marco de registro log4net.

Entre otras cosas, esto agregará automáticamente código a sus métodos que atrapa excepciones y los registra.

Todo depende de si está contento de utilizar el marco de registro log4net o si prefiere hacerlo usted mismo.

0

En vb.net, se puede agregar un calificador "Cuando" a una declaración catch (por ejemplo, 'Catch Ex como ObjectDisposedException When Ex.Message.Contains (' Sorry ')'). Esto se puede usar para anotaciones de registro (por ejemplo, 'Capturar Ex como excepción cuando LoggingFunctionThatReturnsFalse (Ex)' no captará ninguna excepción, pero las registrará todas) y parece una característica que hubiera sido útil en C#. Lo último que escuché, sin embargo, es que la función solo estaba disponible en vb.net (no estoy seguro de qué pasaría si compilara un código utilizando dicha función en vb.net y descompilara en C#).

+0

Correcto: es una de esas características de CLR que C# no expone. Puedes hacer algo bastante parecido capturando todas las 'ObjectDisposedException''s, verificando su' Mensaje' y reiniciando con 'throw;' si no es lo que estabas buscando. No estoy seguro de cómo se compara en el rendimiento, pero una vez más, es una excepción, entonces, ¿a quién le importa? –

+0

@Steven Sudit: al depurar, una excepción no detectada interrumpirá la ejecución donde se lanza; una excepción atrapada y revertida interrumpirá la ejecución donde se vuelva a lanzar. – supercat

+0

No puedo negar que existen diferencias cuando se ejecuta bajo un depurador, pero no escribo mi código para que haya excepciones no detectadas. En el peor de los casos, el bloque catch de nivel superior registra y cierra. –

0

Podría poner algo en el evento Global.asax Application_Error.

He utilizado este método para hacer exactamente lo que describiste en la publicación original, registrando el error y enviando una notificación por correo electrónico.

Cuestiones relacionadas