【问题标题】:Exception - Stack trace line number and message do not match异常 - 堆栈跟踪行号和消息不匹配
【发布时间】:2013-10-25 07:36:38
【问题描述】:

当事情出错时,我们的一些代码出现了一个奇怪的问题 - 在某些情况下,异常消息和堆栈跟踪不匹配。

我们有许多具有类似结构的消息处理程序,如下所示:

public void Handle(AddTelephoneNumber message)
{
    var directory = ClientService.Directory(Context).Result;

    var client = ClientService.ClientLookup(message.ClientNumber, Context).Result;
    if (!client.Item1)
    {
        //Client does not exist
        throw new Exception("Unable to locate client"); //A
    }
    //B Start
    var clientPersonsLnk = client.Item2.Links.Single(l => l.Rel == "client-persons");
    var persons = ClientService.Get<Persons>(clientPersonsLnk.Uri, Context).Result;
    var person = ClientService.Get<Person>(persons.PartyUri(message.Party), Context).Result;
    var phones = ClientService.Get<TelephoneNumbers>(person.Links.Single(l => l.Rel == "person-telephones").Uri, Context).Result;
    var addPhoneLink = phones.Links.Single(l => l.Rel == "telephone-add");

    var newPhone = new TelephoneNumber();
    //Set up the new telephone number, elided from sample
    //B End

    var result = ClientService.Post(addPhoneLink.Uri, newPhone, Context).Result;
    if (result.Item1 == HttpStatusCode.OK || result.Item1 == HttpStatusCode.Created)
        return;
    else
        _logger.WarnFormat("ClientService.Post to {0} returned unexpected response code of: {1}", addPhoneLink.Uri, result.Item1);

    //C
    throw new Exception("Unable to process telephone number addition message");
}

我们观察到的行为如下——如果发生A或C其中之一,我们不可避免地会得到消息最终被传递到错误队列,消息扩展中包含以下信息:

<HeaderInfo>
    <Key>NServiceBus.ExceptionInfo.Message</Key>
    <Value>Unable to process change person name message</Value>
</HeaderInfo>
<HeaderInfo>
    <Key>NServiceBus.ExceptionInfo.Source</Key>
    <Value>ProjectName</Value>
</HeaderInfo>
<HeaderInfo>
    <Key>NServiceBus.ExceptionInfo.StackTrace</Key>
    <Value>System.Exception: Unable to process change person name message
    at ProjectName.Handlers.ChangePersonNameHandler.Handle(ChangePersonName message) in c:\TeamCity\buildAgent\work\6601b33332f54f3c\ProjectName\Handlers\ChangePersonNameHandler.cs:line 45
    at NServiceBus.Unicast.HandlerInvocationCache.Invoke(Object handler, Object message, Dictionary`2 dictionary) in c:\TeamCity\buildAgent\work\d4de8921a0aabf04\src\NServiceBus.Core\Unicast\HandlerInvocationCache.cs:line 63
    at NServiceBus.Unicast.UnicastBus.&lt;&gt;c__DisplayClass2f.&lt;DispatchMessageToHandlersBasedOnType&gt;b__2a(Action dispatch) in c:\TeamCity\buildAgent\work\d4de8921a0aabf04\src\NServiceBus.Core\Unicast\UnicastBus.cs:line 1093</Value>
</HeaderInfo>

(抱歉切换到不同的消息类型 -​​ 我只是想找一个例子)

不过,似乎是,如果异常 message 与 A 点给出的异常匹配,则堆栈跟踪,特别是这一行:

at ProjectName.Handlers.ChangePersonNameHandler.Handle(ChangePersonName message) in c:\TeamCity\buildAgent\work\6601b33332f54f3c\ProjectName\Handlers\ChangePersonNameHandler.cs:line 45

将总是包含 C 点异常的行号。反之亦然,如果我们得到应该在 C 行产生的异常消息,那么堆栈跟踪的行号将指向 A 行。

B 部分中的方法抛出的任何异常似乎都忠实地报告了正确的行号。因此,直接在处理程序中抛出的异常似乎具有这种奇怪的行为,但是我们调用的代码(例如,如果序列不包含任何元素,则从 Linq 抛出的任何异常)都会像往常一样表现。

除了难以置信的胡言乱语,有没有人知道什么会导致这种转变发生?

来自 packages.config:

  <package id="NServiceBus" version="4.0.1" targetFramework="net45" />
  <package id="NServiceBus.CastleWindsor" version="4.0.1" targetFramework="net45" />
  <package id="NServiceBus.Host" version="4.0.1" targetFramework="net45" />
  <package id="NServiceBus.Interfaces" version="4.0.1" targetFramework="net45" />
  <package id="NServiceBus.NHibernate" version="4.0.1" targetFramework="net45" />

或者是否有任何我应该做的进一步调查,更多信息要添加到问题中,等等?

【问题讨论】:

  • 您是否尝试过在 NServiceBus 之外运行 Handler 以查看堆栈跟踪是否正确? NServiceBus 是生成自己的 StackTrace 信息还是使用 .NET 提供的正常异常机制
  • 尝试创建自己的异常类,即TypeAExceptionTypeCException,那我猜是行号错误但异常类型是正确的?
  • 达米安。这听起来很有趣。你可以在某处上传复制品吗?
  • 请显示 try catch 块在哪里。
  • @Def - catch 块在 NServiceBus 代码中 - 我还没有深入研究该代码。

标签: c# nservicebus


【解决方案1】:

1)

private void SomeMethod ( )
{
    try { //some code here }
    catch ( Exception е) 
    {
         throw е : / / CLR thinks that the exception line is there.
    }
}

2) 也可能是C#编译器优化导致的尝试在你的方法中添加属性检查一下:

 [Methodlmpl(MethodImplOptions.Noinlining)]

3) 你在使用隐藏实现细节异常模式吗?

我个人认为是因为编译器优化,因为它可以换行和优化代码。

【讨论】:

    【解决方案2】:

    在同时使用 Lambda 表达式和 Linq 时,我经历了许多奇怪的行为。在运行时和编辑器中(包括频繁的 IDE 崩溃 [与机器无关])。所以,我会在没有 Linq 和 Lambda 表达式的情况下重写 B 部分。

    【讨论】:

      猜你喜欢
      • 2014-01-12
      • 2018-12-03
      • 2011-01-05
      • 1970-01-01
      • 2011-08-10
      • 2011-06-07
      • 2013-04-08
      • 1970-01-01
      • 2017-08-06
      相关资源
      最近更新 更多