0

I'm having a little trouble finishing up my retry logic code. However, I can't figure the missing part. How do I catch and log when it fails and make it retry again with a timer.

Heres my code.

while (true)
{
    var res = await this.httpClientWrapper.......

    if (res.IsSuccessStatusCode)
    {
        var result = await res.Content.......
        this.logger.Info($".......
    }

    if (result.status == "Succesed")
    {
        return true;
    }
    else
    {
        var resContent = await.......
        this.logger.Info($.......
        await Task.Delay(2000).ConfigureAwait(false);
        throw new Exception(resContent);
    }                    
}
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
cade cabde
  • 1
  • 1
  • 1
  • Your `result` variable is declared inside the scope of an `if` block, so you could not access it in the next `if` line. – Rufus L Oct 17 '19 at 21:54
  • https://alastaircrabtree.com/implementing-the-retry-pattern-using-polly/ – Robert McKee Oct 17 '19 at 21:56
  • @RufusL I think the 2nd res may also be `await this.httpClientWrapper.......` Actually... I don't know... – tymtam Oct 17 '19 at 21:57
  • You cannot throw an exception and still loop at the same time. You have to handle the exception inside the loop. Surround the code inside the loop with `try...catch` and handle the exceptions (log, etc) in the `catch`. – Racil Hilan Oct 17 '19 at 22:06

2 Answers2

5

I would recommend that you don't try and reinvent the wheel, and just re-use the Polly framework:

var maxRetryAttempts = 3;

var retryPolicy = Policy
    .Handle<HttpRequestException>()
    .WaitAndRetryAsync(maxRetryAttempts, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,retryAttempt)));

try {
  await retryPolicy.ExecuteAsync(async () =>
  {
    var response = await this.httpClientWrapper.......
    response.EnsureSuccessStatusCode();
  });
}
catch(HttpRequestException ex)
{
  // You've already retried 3 times and failed, do something else here
}
catch(Execption ex)
{
  // You've got a non-HttpRequestException, so we didn't retry.
}

This will retry 3 times, and after that, you get the HttpException that you can catch and do whatever you want. I've implemented an exponential backoff for you, but you can change it to just be every two seconds if you prefer.

Robert McKee
  • 21,305
  • 1
  • 43
  • 57
-2
while(!DoThings()) {
   await Task.Delay(2000).ConfigureAwait(false);
}

public bool DoThings() {
}

With some error handling

while(true) {
   try {
      if(DoThings()) break;
   }
   catch( XXX ex ) {
      log
   }
   await Task.Delay(2000).ConfigureAwait(false);
}

public bool DoThings() {
}
tymtam
  • 31,798
  • 8
  • 86
  • 126