using System.Net; using Microsoft.Extensions.Logging; using Polly; using Polly.Extensions.Http; namespace LittleShop.Client.Http; public class RetryPolicyHandler : DelegatingHandler { private readonly ILogger _logger; private readonly IAsyncPolicy _retryPolicy; public RetryPolicyHandler(ILogger logger, int maxRetryAttempts = 3) { _logger = logger; _retryPolicy = HttpPolicyExtensions .HandleTransientHttpError() .OrResult(msg => !msg.IsSuccessStatusCode && msg.StatusCode != HttpStatusCode.Unauthorized) .WaitAndRetryAsync( maxRetryAttempts, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), onRetry: (outcome, timespan, retryCount, context) => { var reason = outcome.Result?.StatusCode.ToString() ?? outcome.Exception?.Message; _logger.LogWarning( "Retry {RetryCount} after {TimeSpan}ms due to: {Reason}", retryCount, timespan.TotalMilliseconds, reason); }); } protected override async Task SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { return await _retryPolicy.ExecuteAsync(async () => await base.SendAsync(request, cancellationToken)); } }