I have a .net 6 console app that I configured with polly policies depending on what each service does.
Program.cs
try
{
//other setup code
services
.AddHttpClient<ISubjectData, SubjectData>()
.AddTransientHttpErrorPolicy(ConfigurePolicy);
//other setup code
IAsyncPolicy<HttpResponseMessage> ConfigurePolicy(PolicyBuilder<HttpResponseMessage> policy)
{
try
{
return policy.Or<TaskCanceledException>()
.WaitAndRetryAsync(Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromSeconds(10), 5));
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
catch(Exception e)
{
Console.WriteLine(e);
}
The policy is working, however, the program is throwing an unhandled exception which is TaskCanceledException
because the HttpClient
timed out, which isn't being caught by either catch statements or the policy in ConfigurePolicy
.
How can I catch this error, since it is crashing the app?
Also, is there a way to allow Polly to override HTTP client timeout depending on how long it takes to complete all retries?
CodePudding user response:
TL;DR:
You can't catch the exception because you wrapped the policy definition with try
- catch
es.
In case of Polly the policy definition and its execution are separated.
- You define a policy (or a combination of policies)
- You are decorating some method(s) with the above policy
- You are executing the decorated method explicitly or implicitly through the policy.
Whenever you register a typed/named HttpClient
and decorate its methods with an IAsyncPolicy<HttpResponseMessage>
then you are doing only the first two steps.
Whenever you call a method on the HttpClient
, like PostAsync
or SendAsync
that's where the policy is being executed on your behalf / implicitly (via a special DelegatingHandler
).
That's where you can catch the exceptions
- ones which is thrown either by the
HttpClient
(likeTaskCancelledException
,HttpRequestException
, etc.) - or those that are thrown by one of the policies (like
TimeOutRejectedException
,BrokenCircuitException
, etc.)
UPDATE #1
What is confusing to me, is why does a try-catch block that covers my entire Program.cs not catch the exception, but a try-catch block in the scope of the request does? Aren't exceptions propagated back to the original caller? (The original caller would be a method inside my Program.cs file)
Try catch inside the ConfigurePolicy
As I stated above, here you are building the policy, not executing it. So, the try-catch here can be used to detect and resolve misconfiguration.
Try catch inside Program
Yet again the AddHttpClient
and AddTransientHttpErrorPolicy
are just builder methods. They are not executing any http request on your behalf. So, wrapping this code into try-catch can help you to spot misconfiguration.
Your try-catch is covering those exceptions which are thrown by the Main
but not those which are thrown by different threads which are not in the Main
.