Enter a Catch Method in WaitAndRetryAsync

Viewed 180

Goal:
If you have tried the third time and it is not a success. Then you want to use another method.
I would like to to prevent displaying a error message webpage.

Problem:
is it possible to enter a method that is similiar as catch method in WaitAndRetryAsync?

RetryPolicy<HttpResponseMesssage> httpWaitAndRetryPolicy = Policy
    .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .WaitAndRetryAsync
        (3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2. retryAttempt)/2));

Thank you!

2 Answers

You can use ExecuteAsync on your policy and then use ContinueWith to handle final response like this:

 RetryPolicy<HttpResponseMessage>
 .Handle<HttpRequestException>()
 .Or<TaskCanceledException>()
 .WaitAndRetryAsync
     (3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt) / 2))
 .ExecuteAsync(() =>
 {
     //do stuff that you want retry

 }).ContinueWith(x =>
 {
     if (x.Exception != null)
     {
         //means exception raised during execute and handle it
     }

     // return your HttpResponseMessage
 }, scheduler: TaskScheduler.Default);

Following @TheodorZoulias's comment the best practice for use ContinueWith is to explicit set TaskScheduler to defualt, because ContinueWith change the scheduler to Current and maybe cause to deadlock.

First of all the WaitAndRetryAsync returns an AsyncRetryPolicy<T>, not a RetryPolicy<T>, which means that your posted code does not compile.

In case of polly the definition of a policy and the execution of that policy are separated. So, first you define a policy (or a mixture of policies) and then execute it whenever it is needed.

Definition

AsyncRetryPolicy<HttpResponseMessage> retryInCaseOfNotSuccessResponsePolicy = Policy
    .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .WaitAndRetryAsync
        (3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2.retryAttempt) / 2));

Execution

HttpResponseMessage serviceResponse = null;
try
{
    serviceResponse = await retryInCaseOfNotSuccessResponsePolicy.ExecuteAsync(
        async ct => await httpClient.GetAsync(resourceUri, ct), default);
}
catch (Exception ex)
    when(ex is HttpRequestException || ex is OperationCanceledException)
{
    //TODO: log
}

if (serviceResponse == null)
{
    //TODO: log
}
Related