Tengo muchos métodos que están llamando usando Delegate.DynamicInvoke
. Algunos de estos métodos hacen llamadas a la base de datos y me gustaría tener la capacidad de atrapar un SqlException
y no atrapar el TargetInvocationException
y buscar entre sus internos para encontrar lo que realmente salió mal.Cómo volver a lanzar la excepción interna de una TargetInvocationException sin perder el seguimiento de la pila
yo estaba usando este método para volver a lanzar pero despeja el seguimiento de la pila:
try
{
return myDelegate.DynamicInvoke(args);
}
catch(TargetInvocationException ex)
{
Func<TargetInvocationException, Exception> getInner = null;
getInner =
delegate(TargetInvocationException e)
{
if (e.InnerException is TargetInvocationException)
return getInner((TargetInvocationException) e.InnerException);
return e.InnerException;
};
Exception inner = getInner(ex);
inner.PreserveStackTrace();
throw inner;
}
PreserveStackTrace
El método es un método de extensión hasta me fijo gracias a otro puesto (no sé lo que realmente hace) . Sin embargo, esto no parece conservar la traza ya sea:
public static void PreserveStackTrace(this Exception e)
{
var ctx = new StreamingContext(StreamingContextStates.CrossAppDomain);
var mgr = new ObjectManager(null, ctx);
var si = new SerializationInfo(e.GetType(), new FormatterConverter());
e.GetObjectData(si, ctx);
mgr.RegisterObject(e, 1, si);
mgr.DoFixups();
}
Punto interesante a tener en cuenta: ExceptionDispatchInfo en 4.5 significa que ve pilas de llamadas diferentes desde Rx cuando está volviendo a lanzar excepciones dependiendo de si tiene como objetivo 4.0 o 4.5. Los OnErrors no administrados volverán a aparecer con el seguimiento de la pila original cuando se dirijan a 4.5, pero no a 4.0. –