There is a domain exception named DomainException .

 public class DomainException : Exception { } 

There is a class Foo , which has a Throw method that forwards DomainException .

 public class Foo { public void Throw() { throw new DomainException(); } } 

There is a class that calls Throw Foo instance through reflection.

 public static class FooManager { public static void InvokeThrow(object foo) { var methodInfo = typeof(Foo).GetMethod("Throw"); methodInfo.Invoke(foo, null); } } 

There is a piece of code that calls InvokeThrow and tries to catch and handle a DomainException .

 try { FooManager.InvokeThrow(new Foo()); } catch(DomainException ex) { //Do something cool. } 

This desired piece of code will not do because Invoke wraps internal exceptions in a TargetInvocactionException . The required DomainException will DomainException in InnerException really thrown exception.

Question: how to catch and handle DomainException ?

Options:

1 Wrap the call to Invoke in try-catch and throw InnerException .

 public static void InvokeThrow(object foo) { try { var methodInfo = typeof(Foo).GetMethod("Throw"); methodInfo.Invoke(foo, null); } catch(TargetInvocationException ex) { throw ex.InnerException; } } 

The option is bad for the simple reason that we get an exception stack ending with InvokeThrow .

There is a feeling that I am missing something very simple here.

Is there some smart and / or elegant way to catch this exception / call a method not through Invoke / get a normal stack when forwarding InnerException ?

    1 answer 1

    In .NET 4.5 there is a class ExceptionDispatchInfo , which allows to throw other people's exceptions while maintaining the call stack:

     try { var methodInfo = typeof(Foo).GetMethod("Throw"); methodInfo.Invoke(foo, null); } catch(TargetInvocationException ex) { ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); // throw; <--- Ρ€Π°ΡΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ссли ΠΌΠ΅Ρ‚ΠΎΠ΄ Π½Π΅-void, Ρ€Π°Π΄ΠΈ успокоСния компилятора } 

    ExceptionDispatchInfo been added to support async / await - they thus throw the exceptions wrapped in AggregateException from the generated Task-s.