I'm using Polly to catch an exception while calling a Pittney Bowes Geocoder service. I'm using a g1client library that throws a MessageProcessingException. I've wrapped the call in a Polly network policy to retry the call up to 3 times if this exception is thrown, but Visual Studio insists that the exception is "User-Unhandled" What do I need to modify to make this exception be handled? I'm using Visual Studio 2017 community Edition and C# 4.6.1.
try
{
var networkPolicy = Policy
.Handle<MessageProcessingException>()
.Or<Exception>()
.WaitAndRetry(
3,
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
(exception, timeSpan, context) =>
{
System.Diagnostics.Debug.WriteLine("Exception being retried" + exception);
});
geocoderResponse = networkPolicy.Execute(() => geocoderService.Process(geocoderRequest));
}
catch (MessageProcessingException ex)
{
log.Error("MessageProcessingException calling the Geocoder service", ex);
throw ex;
}
catch (Exception ex)
{
log.Error("Exception calling the Geocoder service", ex);
throw ex;
}
The error message is:
g1client.MessageProcessingException occurred
HResult=0x80131500
Message=Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. Client timeout
Source=g1client
StackTrace:
at g1client.UTF8Serializer.DeserializeHashtable(NetworkStream networkStream)
at g1client.UTF8Serializer.GetMessage(NetworkStream networkStream)
at g1client.SocketGatewayConnection.ProcessBytes(Byte[] bytesIn)
at g1client.SocketGatewayConnection.Process(Message message)
at g1client.RemoteService.Process(Message message)
at Midas.Core.PBGeocoder.Geocoder.<>c__DisplayClass27_0.<Bulk2PassGeocode>b__2() in E:\Source Code\GitHub\Midas.Core\Midas.Core.PBGeocoder\Geocoder.cs:line 321
at Polly.Policy.<>c__DisplayClass75_0`1.<Execute>b__0(CancellationToken ct)
at Polly.Policy.<>c__DisplayClass27_0`1.<Execute>b__0(CancellationToken ct)
at Polly.RetrySyntax.<>c__DisplayClass11_0.<WaitAndRetry>b__1(CancellationToken ct)
at Polly.Retry.RetryEngine.Implementation[TResult](Func`2 action, CancellationToken cancellationToken, IEnumerable`1 shouldRetryExceptionPredicates, IEnumerable`1 shouldRetryResultPredicates, Func`1 policyStateFactory)
I'd like to also track down why I'm getting this error, so any help debugging that would be great also. I only get it the first time I call the service with a large request. In this case I was sending 1000 addresses to be processed. The next run the request will be handled in under a second, but the first time it doesn't work.
In Visual Studio, when exceptions are thrown or end up unhandled, the debugger can help you debug these by breaking just like it breaks when a breakpoint is hit.
An exception is a known type of error. An unhandled exception occurs when the application code does not properly handle exceptions. For example, When you try to open a file on disk, it is a common problem for the file to not exist.
Tell the debugger to break when an exception is thrownIn the Exception Settings window (Debug > Windows > Exception Settings), expand the node for a category of exceptions, such as Common Language Runtime Exceptions. Then select the check box for a specific exception within that category, such as System.
Note: you can uncheck Break when this exception type is thrown directly in the exception handler and continue debugging (press F5 ). Visual Studio will add this exception type to the Exception settings and will remember that it shouldn't break on this exception again.
TL;DR You are just seeing the VS debugger breaking on exceptions.
You may be understanding the Visual Studio Debugger's (inherently confusing) terminology user-unhandled exception to mean that the executing codebase as a whole is not handling the exception; this is not the case.
User-unhandled exception in this case means that the exception is first handled other than by your code - here, by the Polly policy.
First, Visual Studio divides code you are debugging into 'my code' aka 'user code', and 'non-user code'. In your scenario, Polly and the Geocoder library will be classified 'non-user code'.
Second, by default, the Visual Studio debugger breaks[+] on exceptions handled by 'non-user code' (but using this potentially confusing and alarming term 'user-unhandled'!).
Visual Studio breaks[+] by default so that you can see the line that triggered the exception as it happened (even if subsequent code will handle it...). So, it sounds (dpdg on debugger settings) as if you are seeing Visual Studio breaking, even though the exception will be handled as configured by the Polly policy. Just press F5/Continue in the debugger, and the subsequent code will resume.
You can also change this behaviour[+] by following the instructions in this article under the heading Tell the debugger to continue on user-unhandled exceptions.
You can further satisfy yourself the Polly policy is working by examining the behaviour of the line System.Diagnostics.Debug.WriteLine("Exception being retried" + exception);
. You should see output from that line - or see it hit if you set a breakpoint on it - if retries are being invoked.
Finally, a Polly retry policy rethrows any final exception if all configured retries have been exhausted. This is intentional - to indicate that eventuality - not a failure.
You correctly have a try { ... } catch (MessageProcessingException ex) { ... }
for this, but the debugger may again misleadingly label that final exception 'user-unhandled' - even though you have a try-catch for it - due to its initially being caught by Polly.
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