2011-11-22 13 views
6

A veces ocurren excepciones. Cuando lo hacen, se registran y luego se analizan. El registro obviamente contiene el seguimiento de la pila y otra información global, pero a menudo falta un contexto crucial. Me gustaría anotar una excepción con esta información adicional para facilitar la depuración post mortem.Anotaciones Excepciones con información adicional sin capturarlas

  • no quiero a try{...}catch{... throw;} ya que cuenta como la captura de una excepción y que hace más difícil la depuración (durante el desarrollo me gustaría la aplicación de parar y el depurador de reaccionar cuando se produce la excepción original y no cuando la excepción más externa no detectada es). Los manejadores de excepciones de primera oportunidad no son una solución, ya que lamentablemente hay demasiados falsos positivos.
  • Me gustaría evitar una sobrecarga excesiva en el caso normal y no excepcional.

¿Hay alguna forma de almacenar elementos clave de contexto (por ejemplo, nombre de archivo procesado o lo que sea) en una excepción de una manera que no capte la excepción?

+1

Interesante. ¿Has pensado envolver el 'try {' y '} catch {... throw;}' en '#if! DEBUG'. En el desarrollo, obtendría la excepción original del sitio de llamadas original. –

+0

¿Qué le parece usar el patrón try {..} catch {.. throw;}, pero cambie sus opciones de Visual Studio para que se rompa cuando se lanza una excepción CLR. – Simon

+2

Parece una buena opción para AOP como PostSharp, pero esto no cumple con su requisito de no alcanzarlo. Simplemente elimina la cantidad de codificación que necesita hacer. –

Respuesta

1

Estoy tomando una foto en este edificio por la sugerencia de Adán de Aop. mi solución sería la unidad en lugar de PostSharp y la única pregunta que tengo es si la excepción se está atrapado en el interior de la invocación, que es probable que ...

 public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) 
    { 
     //execute 
     var methodReturn = getNext().Invoke(input, getNext); 

     //things to do after execution 
     if (methodReturn.Exception != null) 
      methodReturn.Exception.Data.Add("filename", "name of file"); 

     return methodReturn; 
    } 
} 
+0

No me queda claro cómo se vería el código normal al aprovechar esto. Entonces, si 'A' llama' B' llama 'C' y' B' quiere anotar cualquier posible excepción por 'C' con información - ¿cómo usarías esto? –

1

No hay nada malo con el siguiente patrón:

try 
{ 
    // Do Something 
} 
catch (GeneralException ex) 
{ 
    throw new SpecificException(
     String.Format("More specifics ({0}) in message", someData), 
     moreContext, 
     new {even, more, context}, 
     ex); 
} 

Este es precisamente el patrón a usar, por ejemplo, cuando el "Hacer algo" es, por ejemplo, abrir un archivo de algún tipo. La "SpecificException" podría ser "no se puede leer el archivo de configuración".

+0

El problema aquí es doble: en primer lugar, en general es un desorden, y me gustaría hacerlo sistemáticamente. Anidados en jerarquías anidadas en [...] excepciones anidadas no ayudan en un enfoque plano simple; sin mencionar que, en efecto, el costo de lanzar excepciones puede llegar a ser cuadrátrico con stackdepth de esta manera en lugar de lineal. En segundo lugar, y más molesto de inmediato, esto hace que se capture la excepción, lo que complica la depuración tal como se describe en la pregunta. –

+0

En segundo lugar; es muy poco probable que esto dé como resultado una complejidad cuadrática en el tiempo (aunque es necesario que conozca las partes internas de CLR para estar seguro). Sin embargo, eso resuelve los problemas de desorden y depuración. –

+0

Por cierto, esto es lo que básicamente hago ahora; funciona, pero estoy buscando algo mejor :-) –

0

No utilizaría AOP para detectar las excepciones. En su lugar, utilizaría la clase de interceptación para registrar la excepción + todos los argumentos en el método que arrojó la excepción. Y luego deje que la excepción original sea arrojada de nuevo

+0

-1: mala idea. Si la excepción no se propaga, entonces no captura la pila de llamadas completa. Registre la excepción en la parte superior, agregando información adicional cerca del sitio de llamadas, como lo solicita el OP. –

+0

¿Por qué es una mala idea? Algunos frameworks de interceptación simplemente 'throw;' Call stack está reservado – jgauffin

+0

"reserved" = "preserved" – jgauffin

Cuestiones relacionadas