Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflection MethodInfo.Invoke() catch exceptions from inside the method

I have a call to MethodInfo.Invoke() to execute a function through reflection. The call is wrapped in a try/catch block but it still won't catch the exception thrown by the function I'm invoking.

I receive the following message:

Exception was unhandled by the user.


Why does MethodInfo.Invoke() prevent the Exception to be caught outside of the Invoke()?
How do I bypass it?

like image 504
Rodniko Avatar asked Nov 07 '10 09:11

Rodniko


2 Answers

EDIT: As I understand your issue, the problem is purely an IDE one; you don't like VS treating the exception thrown by the invocation of the MethodInfo as uncaught, when it clearly isn't. You can read about how to resolve this problem here: Why is TargetInvocationException treated as uncaught by the IDE? It appears to be a bug / by design; but one way or another, decent workarounds are listed in that answer.

As I see it, you have a couple of options:

  1. You can use MethodInfo.Invoke, catch the TargetInvocationException and inspect its InnerException property. You will have to workaround the IDE issues as mentioned in that answer.

  2. You can create an appropriate Delegate out of the MethodInfo and invoke that instead. With this technique, the thrown exception will not be wrapped. Additionally, this approach does seem to play nicely with the debugger; I don't get any "Uncaught exception" pop-ups.

Here's an example that highlights both approaches:

class Program {     static void Main()     {         DelegateApproach();         MethodInfoApproach();     }      static void DelegateApproach()     {         try         {             Action action = (Action)Delegate.CreateDelegate                                    (typeof(Action), GetMethodInfo());             action();         }         catch (NotImplementedException nie)         {          }      }      static void MethodInfoApproach()     {         try         {             GetMethodInfo().Invoke(null, new object[0]);         }         catch (TargetInvocationException tie)         {             if (tie.InnerException is NotImplementedException)             {               }         }     }      static MethodInfo GetMethodInfo()     {         return typeof(Program)                 .GetMethod("TestMethod", BindingFlags.NonPublic | BindingFlags.Static);     }          static void TestMethod()     {         throw new NotImplementedException();     } } 
like image 83
Ani Avatar answered Oct 02 '22 13:10

Ani


How are you trying to catch the exception? Typically what is thrown from a call to Invoke() is a wrapping exception instance of System.Reflection.TargetInvocationException. The actual exception you're after will be in the InnerException.

try {     method.Invoke(target, params); } catch (TargetInvocationException ex) {     ex = ex.InnerException; // ex now stores the original exception } 
like image 43
Quick Joe Smith Avatar answered Oct 02 '22 13:10

Quick Joe Smith