使用Polly时,VS Debugger中报告了用户未处理的异常 [英] Exception User-Unhandled reported in VS Debugger when using Polly

查看:186
本文介绍了使用Polly时,VS Debugger中报告了用户未处理的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在调用Pittney Bowes Geocoder服务时正在使用Polly捕获异常.我正在使用一个抛出MessageProcessingException的g1client库.如果引发此异常,我将呼叫包装在Polly网络策略中,最多重试3次,但是Visual Studio坚持认为该异常是用户未处理的".我需要修改些什么才能使该异常得到处理? 我正在使用Visual Studio 2017社区版和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;
}

错误消息是:

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)

我还要跟踪为什么会出现此错误,因此任何有助于调试的帮助也将非常有用.我只有在有大量请求时才第一次调用该服务.在这种情况下,我要发送1000个地址进行处理.下次运行该请求将在一秒钟内处理完毕,但是第一次将不起作用.

解决方案

TL; DR您只是看到VS调试器在异常上中断.

您可能正在理解Visual Studio调试器的(本来就是混乱的)术语用户未处理的异常,这意味着整个执行的代码库都没有处理该异常;不是这种情况.

用户未处理的异常在这种情况下意味着该异常首先被处理我的代码"(又称用户代码")和非用户代码" .在您的方案中,Polly和Geocoder库将归类为非用户代码".

第二,默认情况下,Visual Studio调试器会在由非用户代码"处理的异常上中断[+](但使用此可能引起混淆和令人震惊的术语用户- un 已处理"!) .

默认情况下,Visual Studio会中断[+],以便您可以查看在异常发生时触发异常的行(即使后续代码可以处理该行……).因此,听起来(在调试器设置上为dpdg)就像您看到Visual Studio中断一样,即使异常将按照Polly策略的配置进行处理.只需在调试器中按F5/Continue,随后的代码就会恢复.

您还可以通过遵循本文中的说明,标题为告诉调试器继续处理用户未处理的异常 .

通过检查System.Diagnostics.Debug.WriteLine("Exception being retried" + exception);行的行为,您可以进一步满足Polly策略的要求.您应该看到该行的输出-如果在其上设置了一个断点,则会看到命中-如果正在调用重试.


最后,如果所有配置的重试都已用尽,则Polly重试策略会抛出任何最终异常.这是故意的-表示可能发生-不是失败.

为此您正确地具有try { ... } catch (MessageProcessingException ex) { ... },但是调试器可能会再次误导该最终异常为用户未处理",即使您有尝试捕获的原因也是如此,因为该异常最初是被Polly捕获的./p>

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.

解决方案

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.

这篇关于使用Polly时,VS Debugger中报告了用户未处理的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆