Is there a way in Polly to retry all exceptions apart from those which are specified.. for example:
var p = Policy
.Handle<HttpListenerException>(e => !(e.NativeErrorCode == 1))
.Or<Exception>()
.RetryAsync();
Here i have picked a slightly contrived situation where i would want to NOT retry when the NativeErrorCode == 1
?
I initially hoped that this will retry if any value other than 1, and any other Exception dealt with by the .Or<Exception>()
..
What is actually happening, is that the .Or<Exception>
will also catch the NativeErrorCode == 1
, even though it was excluded from above? I think..
One option i considered, but not tested... (no error checking ;p)
var p = Policy
.Handle<Exception>(e => SomethingMoreComplex(e) == true)
.RetryAsync();
private bool SomethingMoreComplex(Exception e)
{
if (e is HttpListenerException t)
{
if (t.NativeErrorCode == 1) return false;
}
return true;
}
is that threadsafe? :|
If you look at the Policy.HandleSyntax.cs file then you can see how the Handle<T>
methods have been defined:
public partial class Policy
{
public static PolicyBuilder Handle<TException>() where TException : Exception
=> new PolicyBuilder(exception => exception is TException ? exception : null);
public static PolicyBuilder Handle<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception
=> new PolicyBuilder(exception => exception is TException texception && exceptionPredicate(texception) ? exception : null);
...
}
public partial class Policy<TResult>
{
public static PolicyBuilder<TResult> Handle<TException>() where TException : Exception
=> new PolicyBuilder<TResult>(exception => exception is TException ? exception : null);
public static PolicyBuilder<TResult> Handle<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception
=> new PolicyBuilder<TResult>(exception => exception is TException texception && exceptionPredicate(texception) ? exception : null);
...
}
PolicyBuilder
class, which has an internal ctor.
Policy
class does not have a public ctor.
Policy
instance, that's why it does not make sense to create extension methods for the Policy
class.Here is one way to overcome on these limitations:
public static class PolicyExt
{
public static PolicyBuilder HandleExcept<TException>() where TException : Exception
=> Policy.Handle((Exception exception) => exception is TException is false);
public static PolicyBuilder HandleExcept<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception
=> Policy.Handle((Exception exception) => exception is TException is false || exception is TException texception && !exceptionPredicate(texception));
}
public static class PolicyExt<TResult>
{
public static PolicyBuilder<TResult> Handle<TException>() where TException : Exception
=> Policy<TResult>.Handle((Exception exception) => exception is TException is false);
public static PolicyBuilder<TResult> Handle<TException>(Func<TException, bool> exceptionPredicate) where TException : Exception
=> Policy<TResult>.Handle((Exception exception) => exception is TException is false || exception is TException texception && !exceptionPredicate(texception));
}
And finally here is a quick test:
var policy = PolicyExt.HandleExcept<Exception>(ex => ex is NotSupportedException)
.WaitAndRetry(2, _ => TimeSpan.FromSeconds(2));
//Or just:
//var policy = PolicyExt.HandleExcept<NotSupportedException>()
// .WaitAndRetry(2, _ => TimeSpan.FromSeconds(2));
policy.Execute(() =>
{
Console.WriteLine("Have been called");
throw new NotSupportedException();
});
Output:
Have been called
Unhandled exception. System.NotSupportedException: Specified method is not supported.
NotSupportedException
the retry logic is not triggered.policy.Execute(() =>
{
Console.WriteLine("Have been called");
throw new Exception("Custom");
});
Then the output will be the following:
Have been called
Have been called
Have been called
Unhandled exception. System.Exception: Custom
So, the retry is triggered.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With