Search code examples
c#dotnet-httpclienthttp-status-codespollyretry-logic

Polly v8 - Retrying specific status codes using the PredicateBuilder


I am using Polly v8 and .NET framework 4.7.2 to retry on specific status responses only. However, when trying to restrict the retry to only these statuses the code will no longer invoke the retry behaviors.

It's worth noting that adding a Handle on HttpRequestException would work but begins to retry on additional status codes where the preference is just to fail fast and log

Please see the below example:

public ResiliencePipilineBuilder<HttpResponseMessage> BuildStrategy()
{
    var statusCodes = new List<HttpStatusCode>
    {
        HttpStatusCode.InternalServerError
    };

    PredicateBuilder<HttpResponseMessage> predicateBuilder = new PredicateBuilder<HttpResponseMessage>()
        // .Handle<HttpRequestException>()  NOTE: this would work see explanation
        .HandleResult(response => statusCodes.Contains(response.StatusCode));

    ...

    return new ResiliencePipilineBuilder<HttpResponseMessage>()
        .AddRetry(new RetryStrategyOptions<HttpResponseMessage>()
        {
            ShouldHandle = predicateBuilder,
            ...
        });
}

public async Task<Data> SendIt()
{
    var strategy = BuildStrategy();

    var result = strategy.ExecuteAsync(async token => 
    {
        var response = await client.SendAsync()

        response.EnsureSuccessStatusCode();

        ...
    })
}

Can HandleResult be used by itself to only catch the requests I want in the new v8 style? Would I have to revert to the v7 approach instead?

The Polly docs do show both approaches (Handle and HandleResult) but as a pair rather than individually


Solution

  • The root cause of your problem is not inside the strategy definition rather than inside the decorated method:

    response.EnsureSuccessStatusCode();
    

    This code will throw an HttpRequestException if the IsSuccessStatusCode returns false. So, whenever the status code is not in the following range: 200-299.

    If you remove this check then your strategy will work in the excepted way.