Michel van Engelen
Michel van Engelen

Reputation: 2869

Polly WaitAndRetry with final exception does nothing

I execute calls to an external service that is not very stable, and thus throws WebExceptions.
I want to retry a few times and after the last attempt I want to throw the last error received.

This is my attempt with Polly (v6.1.1):

public static Policy WaitAndRetryPolicy<T>(short nrOfRetryAttempts = 5) where T : Exception
{
    var waitAndRetry = Policy
        .Handle<T>()
        .WaitAndRetry(nrOfRetryAttempts, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

    var fallbackForLastError = Policy
        .Handle<T>()
        .Fallback(
            fallbackAction: () => { },
            onFallback: (ex) => { throw ex; });

    return Policy.Wrap(fallbackForLastError, waitAndRetry);
}

Caller, legacy VB.Net:

Dim retryPolicy = Policies.WaitAndRetryPolicy(Of WebException)()
Dim theResult = retryPolicy.
    ExecuteAndCapture(Function()
                          Return aProxy.GetSomething(a, b)
                      End Function).Result

When I run the code as depicted above, theResult stays null and it seems like the service is not called. If I just use the WaitAndRetryPolicy without the Fallback function, the service is called and the retry mechanism works as expected (without throwing the exception of course).

How can I achieve my goal, without having to check PolicyResult.FinalException in the caller code?

Upvotes: 2

Views: 3610

Answers (2)

mountain traveller
mountain traveller

Reputation: 8156

To have Polly rethrow any final exception, rather than capture it into PolicyResult.FinalException, simply execute the policy with the .Execute(...) or .ExecuteAsync(...) overloads, rather than .ExecuteAndCapture(...) or .ExecuteAndCaptureAsync(...)

Upvotes: 6

RichyP7
RichyP7

Reputation: 29

I don´t know about the last exception but i have implemented a very similar behaviour with Retry and CircuitBreakerException(with Wrapping). So you can try 3 times and throw a circuitbreakerexception after 2 failures. Then you are able to react on the last exception.

Policy
.Handle<SomeExceptionType>()
.CircuitBreaker(2, TimeSpan.FromMinutes(x));

Upvotes: 0

Related Questions