I'm using Polly to retry HttpClient attemnpts :
services.AddHttpClient<JoinPackageApiClient>(jp => { jp.BaseAddress = new Uri(appSettings.JoinPackageWS.BaseUrl); })
.AddPolicyHandler(GetRetryPolicy(appSettings, serviceProvider))
Where GetRetryPolicy is :
private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(AppSettings appSettings, ServiceProvider serviceProvider)
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode != HttpStatusCode.OK)
.Or<TimeoutRejectedException>()
.Or<TaskCanceledException>()
.Or<OperationCanceledException>()
.WaitAndRetryAsync(appSettings.PollySettings.RetryAttempts, (retryAttempt, c) =>
{
return TimeSpan.FromSeconds(2);
}, onRetry: (response, delay, retryCount, context) =>
{
//█how can I access the full(!) HttpClient's URI here ?
//e.g. : https://a.com/b/c?d=1
});
}
Question:
Looking at the onRetry parameter, I want to log the full URL attempt in the onRetry section.
How can I get the full URI in that section ?
I was wrong when I have stated in my comment that this is not possible.

I have to correct myself: Yes, it is doable and it is actually pretty easy. :)
All you need to do is to use a different overload of AddPolicyHandler
public static IHttpClientBuilder AddPolicyHandler (this IHttpClientBuilder builder, Func<IServiceProvider,HttpRequestMessage,IAsyncPolicy<HttpResponseMessage>> policySelector);
So, whenever you call the AddPolicyHandler you have to provide a function, which
IServiceProvider instance to be able to access to any DI registered serviceRequestUri propertyIAsyncPolicy<HttpResponseMessage>So, you have to modify the registration code like this:
services.AddHttpClient<JoinPackageApiClient>(jp => ...)
.AddPolicyHandler((provider, request) => GetRetryPolicy(appSettings, provider, request));
and the GetRetryPolicy method like this:
private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy(
AppSettings appSettings,
IServiceProvider serviceProvider,
HttpRequestMessage request)
=> HttpPolicyExtensions
.HandleTransientHttpError()
...
.WaitAndRetryAsync(appSettings.PollySettings.RetryAttempts,
(_, __) => TimeSpan.FromSeconds(2),
(response, delay, retryCount, context) =>
{
var url = request.RequestUri;
// ...
});
The good news is that the url will change whenever you issue a new request.
(In my test client I have set the BaseAddress to http://httpstat.us)
When I run this test
await client.GetAsync("/200");
try
{
await client.GetAsync("/401");
}
catch { }
await client.GetAsync("/403");
then the retry triggered 4 times (2x for 401 and 2x for 403). The onRetry received the related HttpRequestMessage so, the logging was accurate.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With