当事情出错时,我们会看到一些奇怪的问题 - 在某些情况下,异常消息和堆栈跟踪不匹配.
我们有许多具有类似结构的消息处理程序,如下所示:
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");
}
Run Code Online (Sandbox Code Playgroud)
我们观察到的行为如下 - 如果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.<>c__DisplayClass2f.<DispatchMessageToHandlersBasedOnType>b__2a(Action dispatch) in c:\TeamCity\buildAgent\work\d4de8921a0aabf04\src\NServiceBus.Core\Unicast\UnicastBus.cs:line 1093</Value>
</HeaderInfo>
Run Code Online (Sandbox Code Playgroud)
(切换到不同消息类型的道歉 - 我只是想找一个例子)
但是,似乎包含的是,如果异常消息与A点给出的异常消息匹配,那么堆栈跟踪,特别是此行:
at ProjectName.Handlers.ChangePersonNameHandler.Handle(ChangePersonName message) in c:\TeamCity\buildAgent\work\6601b33332f54f3c\ProjectName\Handlers\ChangePersonNameHandler.cs:line 45
Run Code Online (Sandbox Code Playgroud)
将在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" />
Run Code Online (Sandbox Code Playgroud)
或者是否有任何进一步的调查我应该做,更多信息添加到问题等?
小智 4
1)
\n\nprivate void SomeMethod ( )\n{\n try { //some code here }\n catch ( Exception \xd0\xb5) \n {\n throw \xd0\xb5 : / / CLR thinks that the exception line is there.\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n2)也可能是C#编译器优化引起的,尝试在你的方法中添加该属性来检查:
\n\n [Methodlmpl(MethodImplOptions.Noinlining)]\nRun Code Online (Sandbox Code Playgroud)\n\n3)您是否使用隐藏实现细节异常模式?
\n\n在我看来,这是因为编译器优化,因为它可以稍微切换线路并优化代码。
\n