0

I have the below mapper json file, which tells me for a given exception, which error handling policy I want to use.

{
  "ExceptionMappers": [
   {
     "ExceptionName": "TimeoutException",
     "ExceptionType": "Transient",
  "Policy": "WaitAndRetry",
  "WaitType": "Linear"
},
{
  "ExceptionName": "DivideByZeroException",
  "ExceptionType": "Permanent",
  "Policy": "CircuitBreaker"
},
{
  "ExceptionName": "StackOverflowException",
  "ExceptionType": "LogOnly",
  "Policy": "WaitAndRetry",
  "WaitType": "Linear"
}
]
 }

Then using the below code I am trying to get the type of exception and apply a policy using which the action can be called. But here I am stuck, how to get the exception type from a string name.

   public void Execute(Action action, string exceptionName)
    {
        var filePath = @"appsetting.json";
        var exceptionMapperJson = System.IO.File.ReadAllText(filePath);
        var rootNode = JsonConvert.DeserializeObject<RootObject>(exceptionMapperJson);

        var exceptionNode = rootNode.ExceptionMappers.FirstOrDefault(e => e.ExceptionName.Equals(exceptionName));
        var exceptionObject = Type.GetType(exceptionName);

        if (exceptionNode != null)
        {
            // Here I need the exception from the string value
            Policy.Handle<TimeoutException>().Retry().Execute(action);
        }
        else
        {
            // No Policy applied
            Policy.NoOp().Execute(action);
        }

    }
Developer
  • 759
  • 2
  • 9
  • 24
  • 1
    Possible duplicate of [How do I use reflection to call a generic method?](https://stackoverflow.com/questions/232535/how-do-i-use-reflection-to-call-a-generic-method) – thehennyy Jan 04 '18 at 12:09

1 Answers1

1

Per @thehennyy 's comment, Jon Skeet's answer to a similar question covers how to use reflection to invoke a generic method when the generic type is known only at runtime. The slight difference from the linked answer: because .Handle<TException>() is a static method on Policy, pass null as the first argument to MethodInfo.Invoke().

Alternatively, because Polly offers Handle clauses which can take a predicate, you could simply:

var exceptionType = Type.GetType(exceptionName);
if (exceptionNode != null)
{
    Policy.Handle<Exception>(e => exceptionType.IsAssignableFrom(e.GetType())) // etc
}

This live dotnetfiddle example demonstrates it working.


Or, make your wrapper method itself generic:

public void Execute<TException>(Action action) where TExecption : Exception
{
    // reverses the approach: 
    // you'll want a typeof(TException).Name, to get the string name of the exception from TException

    // Then you can just Policy.Handle<TException>(...) when you construct the policy
}

As another refinement, you could consider constructing the policies only once at startup, and placing them in PolicyRegistry

mountain traveller
  • 7,591
  • 33
  • 38