2012-02-27 16 views
16

Tengo el siguiente código:captura de excepciones, añadir datos y volver a lanzar que

try 
{ 
    OnInitialize(); 
} 
catch (PageObjectLifecycleException exception) 
{ 
    exception.OldLifecycleState = CurrentLifecycleState; 
    exception.RequestedLifecycleState = LifecycleState.Initialized; 
    throw exception; 
} 

cojo una excepción, añadir algunos datos más a ella, y volver a lanzar la misma. ReSharper mí (correctamente) que está destinado a volver a lanzar posiblemente advierte y sugiere cambiar a:

throw; 

Pero me pregunto: ¿Será este volver a lanzar correctamente el modificado excepción o la original sin modificar?

Editar: En respuesta a los comentarios "Pruébalo y mira": Soy nuevo en C#, procedente de C++. En C++ a menudo encuentras un comportamiento indefinido en casos de esquina como este y estoy interesado en saber si lo que quiero realmente es cómo funciona oficialmente.

+6

probarlo y ver lo que sucede? –

+0

volverá a lanzar lo que indique la referencia también - en su caso, la "excepción" modificada. –

Respuesta

8

Lanzará la referencia a la excepción modificada.

Sin embargo, no estoy seguro de si este es un buen estilo de programación. Considere crear una nueva excepción y agregue la excepción PageObjectLifecycleException como su excepción interna. De esta forma, el código de manejo puede estar seguro de si tiene la información adicional correcta o no.

+0

Yo también, esto es un verdadero bug hider. El bloque de captura externo pisoteando los datos pasó de uno más profundo, por ejemplo. –

+0

El ejemplo del código está simplificado. No se sobrescribirán los datos existentes, solo se suministran algunos datos adicionales faltantes. –

+0

@TonyHopkinson 'Exception.Data' parece que se supone que es para este propósito ([aquí] (https://msdn.microsoft.com/en-us/library/system.exception.data (v = vs.110)) .aspx)) – drzaus

2

Se relanzó la excepción actual, aunque no estoy seguro de que su patrón sea muy agradable y fácil de mantener.

22

Sé que la respuesta ya se ha elegido, pero aquí hay un poco más de información sobre el tema.

try { 
    // code 
} 
catch(Exception e) { 
    throw e; 
} 

El código anterior cuando se compila en IL producirá una llamada a throw pasando una referencia a la excepción manejado como un argumento. Como probablemente sepa, puede llamar al throw desde cualquier parte de su código para hacer una excepción.

try { 
    // code 
} 
catch(Exception e) { 
    throw; 
} 

El código anterior cuando compila en IL producirá una llamada a rethrow. Esto es diferente a throw como rethrow se utiliza para indicar que el bloque en el que se manejó la excepción ha decidido por alguna razón no manejarlo y, por lo tanto, debe ofrecerse la responsabilidad a un bloque catch de orden superior (siguiente uno arriba).

El método rethrowconserva el seguimiento de la pila de llamadas actual para poder rastrear el origen de la excepción. Sin embargo, el método throw inicia un nuevo rastreo de pila de llamadas. Creo que esto tiene sentido una vez que entiendes para qué se usan los dos métodos.

En mi experiencia utiliza throw exception; cuando se quiere lanzar una excepción por alguna razón (por ejemplo, la validación de un objeto fallidos) y se usaría throw; en un comunicado de captura después de que haya realizado alguno de registro (es decir, mientras aún tiene acceso a información útil en el objeto que falló la validación antes de pasar las responsabilidades de manejo de excepciones a un nivel superior).

En su ejemplo, le sugiero que, si necesita agregar más información a una excepción, tiene razones para crear una excepción completamente nueva y subirla. Entonces usaría el método throw exception; donde "excepción" es una nueva excepción que contiene la información adicional y la excepción lanzada originalmente.

Espero que ayude!

James

9

Puede añadir la información adicional en los datos y volver a emitir la excepción con throw por lo que mantiene su forma original y la pila de llamadas

try 
{ 
    ... 
} 
catch (PageObjectLifecycleException exception) 
{ 
    exception.Data.Add("additional data", "the additional data"); 
    throw; 
} 
+2

Esto realmente debería ser la respuesta aceptada, para eso es 'Data'. Siempre y cuando se proteja contra conflictos clave, y tenga en cuenta que cualquier información contenida en el diccionario 1) se propaga por la cadena de llamadas y 2) puede modificarse en el camino, es una gran manera de agregar información útil para facilitar la depuración. –

Cuestiones relacionadas