Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a query - Could you help me If have completed the number RetryCount in WaitAndRetryAsync but still not getting StatusCode.OK . Then I want to through the exception. So How can I do this?

Or is there any way if a number or retry count is completed, so is there any way that can provide functionality OnRetryComplete so that we can give any message that we have retried multiple times but not able to get the success code and can return any method.

var policy = Policy
        .Handle<Exception>()
        .OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
        .WaitAndRetryAsync(2, _ => TimeSpan.FromMilliseconds(200));
    int count = 0;
    var responseMessage = await asyncPolicy.ExecuteAsync(async () =>
        string requestJson = JsonSerializer.Serialize(eligRequest, new JsonSerializerOptions
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        using var content = new StringContent(requestJson, Encoding.UTF8, "application/json");
        HttpResponseMessage result = await httpClient.PostAsync("test/api/ate", content);
        return result.EnsureSuccessStatusCode();
    return responseMessage;
catch (HttpRequestException error)
    logger.LogError(error);
    throw new CustomException();
                Retry will throw the original exception whenever it runs out of the retry attempts or when the result is unhandled from the policy perspective.
– Peter Csala
                Oct 4, 2021 at 13:38
                The problem is when we are retrying the code due to failure, after retrying is Complete, means - if we have to retry 2 times, after retrying it I want to send custom exception. Note: After rechecking that Number of retry is competed.
– Sheriff
                Oct 4, 2021 at 14:06

Polly itself throws that exception out if it is not able to complete the operation within the given retry count and time.

public async Task Main()
    var httpClient = new HttpClient();
    AsyncRetryPolicy _retryPolicy;
    _retryPolicy = Policy.Handle<Exception>()
                    .WaitAndRetryAsync(2, retryAttempt =>
                        Console.WriteLine("Attempt... " + retryAttempt);
                        var timeToRetry = TimeSpan.FromSeconds(2);
                        Console.WriteLine($"Waiting {timeToRetry.TotalSeconds} seconds");
                        return timeToRetry;
        await _retryPolicy.ExecuteAsync(async () =>
            var response = await httpClient.GetAsync("https://urlnotexist.com/api/products/1");
            response.EnsureSuccessStatusCode();
    catch (Exception ex)
        Console.WriteLine("Final Throw");
        //Validate your logic here and throw ex.

The above code will generate output as below:

Attempt... 1
Waiting 2 seconds
Attempt... 2
Waiting 2 seconds
Final Throw

So in the catch block, you will get the exception. From there you can validate your logic and throw it further or log it.

Thanks for the response, but when we will use try catch block so vert first time it will come in catch block, and retry policy behaviour wll break or won't work. – Sheriff Oct 4, 2021 at 13:03 within the given retry count and time Retry does not have any time constraint. You can combine a retry and a timeout but that's an another story. :) – Peter Csala Oct 5, 2021 at 5:02

I think you are looking for ExecuteAndCaptureAsync and PolicyResult.

PolicyResult exposes several useful properties to deal with the thrown exception:

  • Outcome: It is Failure if all retries failed without success
  • FinalException: The original exception which was thrown by the decorated code
  • PolicyResult<string> result = await policy.ExecuteAndCaptureAsync(async () => await ...);
    if(result.Outcome == OutcomeType.Failure && result.FinalException != null)
        throw new CustomException();
    

    Please also change your Policy to indicate that in case of success you want to return with a string:

    var policy = Policy<string>
            .Handle<Exception>()
            .OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
            .WaitAndRetryAsync(2, _ => TimeSpan.FromMilliseconds(200));
    

    This code is working fine which I have pasted in my question. Sorry for the inconvenience.

    Thankyou all for your efforts.

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.