2013-10-25 5 views
10

Мы видим странную проблему с некоторыми из нашего кода, когда все идет вразрез - в определенных обстоятельствах сообщение об исключении и трассировка стека не совпадают.Исключение. Номер строки трассировки и сообщение не совпадают.

У нас есть несколько обработчиков сообщений с аналогичной структурой, как в следующем:

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> 

(Извинения для переключения на другой тип сообщения - я просто хотел найти пример)

Что, кажется, состоит, однако, заключается в том, что если исключение сообщение соответствует приведенному в точке А, то трассировка стека, а именно эта линия:

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" /> 

Или есть ли дальнейшее расследование, я должен сделать, больше информации, чтобы добавить к вопросу, и т.д.?

+0

Вы пробовали использовать Handler вне NServiceBus, чтобы проверить, правильна ли функция stacktrace? Создает ли NServiceBus собственную информацию StackTrace или использует механизм нормального исключения, предоставляемый.NET – Jehof

+1

Попробуйте создать свои собственные классы исключений, то есть 'TypeAException' и' TypeCException', тогда я бы предположил, что номер строки неверен, но тип исключения верен? – flindeberg

+0

damien. это звучит весело. можете ли вы загрузить репродукцию где-нибудь? – Simon

ответ

3

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) Вы используете шаблон исключения деталей реализации скрытия?

По моему мнению, это потому, что оптимизация компилятора, потому что он может немного переключать линии и оптимизировать код.

0

Я испытал много странных поведений при использовании Лямбда-выражений и Linq вместе. И во время выполнения, и в редакторе (включая частые сбои IDE [независимые от машины]). Итак, я бы переписал раздел B без выражений Linq и Lambda.

Смежные вопросы