Sam
Sam

Reputation: 1514

Getting the correct Exception type out of a call to Invoke (reflection)

In our integration project we are dynamically delegating to a series of specific Processor objects using Reflection.

var genericType = typeof(IMessageProcessor<>).MakeGenericType(parseResponse.DomainMessage.GetType());

var miProcessMessage = genericType.GetMethod("ProcessMessage");
miProcessMessage.Invoke(processor, new object[] { parseResponse.DomainMessage });

Now, in certain situations, one of the processors needs to throw a specific Exception, in this case when he doesn't find a file in the expected location.

throw new ResourceNotFoundException(string.Format("Could not find file {0}", filePath));

Our processor wants to check on this exception to determine whether processing needs to be retried or aborted (based on a time-based mechanism, which is not relevant here).

catch(ResourceNotFoundException ex)
{
   // do stuff
}

The problem is that the invoke apparently "swallows" the specific ResourceNotFoundException and rethrows a System.Exception saying "Exception has been thrown by the target of an invocation."

Is there any way of preserving the fact through Reflection that a ResourceNotFoundException was actually thrown and not an Exception?

Upvotes: 1

Views: 420

Answers (1)

MethodBase.Invoke(Object, Object[]) wraps any exception thrown by the invoked method in a TargetInvocationException. You can access the inner exception and either process it directly, or rethrow it to be processed further up the stack as in the following example:

var genericType = typeof(IMessageProcessor<>).MakeGenericType(parseResponse.DomainMessage.GetType());
var miProcessMessage = genericType.GetMethod("ProcessMessage");
try {
    miProcessMessage.Invoke(processor, new object[] { parseResponse.DomainMessage });
catch (TargetInvocationException ex)
{
    throw ex.InnerException;
}

Note however that this will replace the inner exception's stack trace. A (technically unsupported) way of preserving the stack trace is described in this answer on SO.

Upvotes: 2

Related Questions