2

I'm attempting to log something before retrying. What is the correct syntax of logging info before retry happens?

Here's a sample code similar to my actual code:

var policy = Polly.Policy
    .Handle<SomeExceptionType>()
    .WaitAndRetryAsync(
    retryCount: this.maxRetryCount,
    sleepDurationProvider: (_, e, context) =>
    {
        var waitTimeSpan = TimeSpan.FromSeconds(1);
        if (e != null && e is SomeExceptionType someException)
        {
            var retryAfterFromException = someException.Headers?.RetryAfter.Delta;
            if (retryAfterFromException > TimeSpan.Zero)
            {
                waitTimeSpan = retryAfterFromException.GetValueOrDefault();
            }
        }
    
        return waitTimeSpan;
    },
    onRetryAsync: (e, timeSpan, retryCount) => 
       this.logger.LogInfo($"Request failed with {result.Result.StatusCode}. Waiting {timeSpan} before next retry. Retry attempt {retryCount}"));

This gives syntax error because LogInfo returns void. What's the right approach of logging?

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Satashree Roy
  • 365
  • 2
  • 9
  • 1
    Please be aware of this `result.Result.StatusCode` code might throw `NullReferenceException` if an Exception has been thrown during the request. Please use the [null-conditional operator](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-): `result?.Result?.StatusCode` – Peter Csala Jun 30 '22 at 14:12

2 Answers2

2

Based on your sleepDurationProvider delegate, you try to use this overload:

public static AsyncRetryPolicy WaitAndRetryAsync(
   this PolicyBuilder policyBuilder, 
   int retryCount,
   Func<int, Exception, Context, TimeSpan> sleepDurationProvider, 
   Func<Exception, TimeSpan, int, Context, Task> onRetryAsync)

That means the expected onRetryAsync should look like this:

(exception, sleepDuration, retry, context) => 
{
  this.logger.LogInfo(...);
  return Task.CompletedTask;
}
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
1

Change it to

onRetryAsync: (e, timeSpan, retryCount, context) => { 
   this.logger.LogInfo($"Request failed with {result.Result.StatusCode}. Waiting 
    {timeSpan} before next retry. Retry attempt {retryCount}"); 
   return Task.CompletedTask; 
});`

as onRetryAsync expects a Task return type

user1672994
  • 10,509
  • 1
  • 19
  • 32
  • Unfortunately there is no such overload of `WaitAndRetryAsync` which anticipates this `onRetryAsync` delegate and the OP's `sleepDurationProvider` function. – Peter Csala Jun 30 '22 at 14:07