Reputation: 5714
I've written a custom exception AbortTestException, which is pretty simple:
class AbortTestException : Exception
{
public AbortTestException(string message)
: base(message) { }
}
Then I have a function that will throw it:
class Foo
{
public void Throws()
{
throw new AbortTestException("hi");
}
}
And Throws() gets called via method reference:
class Program
{
static void Main(string[] args)
{
Type myType = (typeof(Foo));
var method = myType.GetMethod("Throws");
try
{
method.Invoke(new Foo(), null);
}
catch (AbortTestException ex)
{
Console.WriteLine("AbortTestException");
}
catch (Exception ex)
{
Console.WriteLine("Exception");
}
}
}
However, something weird happens. Even though Throws rises an AbortTestException, the catch(Exception) block gets used (instead of the catch(AbortTestException) block). I tried putting the "throw new AbortTestException("hi")" portion in the try block itself, and verified that the correct catch block is used.
Is there some reason an exception would be re-cast when emitted via MethodInfo.invoke()?
Upvotes: 1
Views: 483
Reputation: 113242
Remember that catching Exception
will match any exception that isn't caught by a more specific catch block before it:
Type myType = (typeof(Foo));
var method = myType.GetMethod("Throws");
try
{
try
{
method.Invoke(new Foo(), null);
}
catch (AbortTestException ex)
{
Console.WriteLine("AbortTestException");
}
catch(TargetInvocationException tie)
{
throw tie.InnerException;
}
catch (Exception ex)
{
Console.WriteLine("Exception");
}
}
catch(AbortTestException ate)
{
Console.WriteLine("AbortTestException after re-throw from TargetInvocationException");
}
Upvotes: 0
Reputation: 7154
Did you check the nested Exception? My guess the original exception (AbortTest...) is wrapped in a nested one. The nested Exception will be in the InnerException property of the one which is caught by your code
Upvotes: 0
Reputation: 17307
http://msdn.microsoft.com/en-us/library/4k9x6bc0.aspx
Per the MSDN a TargetInvocationException is thrown if the invoked method or constructor throws an exception.
Upvotes: 5