Почему неполный stack trace?
От: MozgC США http://nightcoder.livejournal.com
Дата: 05.10.09 11:51
Оценка:
Добрый день,

Есть функция LoadPendingOrdes():

private void LoadPendingOrders()
{
    try
    {
        //...
    }
    catch (XxxException ex)
    {
        LogHelper.ShowAndLogException(..., ex);
    }
}


LogHelper.ShowAndLogException() логирует сообщение и выводит сообщение пользователю.
Функция LoadPendingOrders() вызывается в обработчике FormLoad формы и в обработчике нажатия на кнопку Refresh.
Но в логе смотрю и вижу такой stack trace:

Stack trace:
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteNonQuery()
at RA.DAL.PendingOrdersAccessor.GetPendingOrders()
at RA.WinForms.CheckOnlineOrdersForm.LoadPendingOrders()


Вопрос: почему в Stack trace не видно откуда вызвана LoadPendingOrders() : из Form_Load() или из btnRefresh_Click() ?
Re: Почему неполный stack trace?
От: Пельмешко Россия blog
Дата: 05.10.09 12:38
Оценка: 5 (1) +1
Здравствуйте, MozgC, Вы писали:

MC>Вопрос: почему в Stack trace не видно откуда вызвана LoadPendingOrders() : из Form_Load() или из btnRefresh_Click() ?


Такое поведение by design + ещё может из-за инлайнинга не быть некоторых методов, но это не Ваш случай.
Может запрашивать Environment.StackTrace в catch'е?
Re[2]: Почему неполный stack trace?
От: MozgC США http://nightcoder.livejournal.com
Дата: 05.10.09 23:04
Оценка:
Здравствуйте, Пельмешко, Вы писали:

П>Такое поведение by design

А где можно почитать об этом поведении by design? Я смотрю лог ошибок, в некоторых местах stack trace содержит обработчик нажатия на кнопку к примеру (исключение происходит не в самом обработчике), а в некоторых местах — нет. Странно...

П>Может запрашивать Environment.StackTrace в catch'е?

Как вариант, но там конечно слишком избыточная информация для большинства случаев.
Re: Почему неполный stack trace?
От: yrtimiD Израиль  
Дата: 06.10.09 20:48
Оценка: 10 (1)
Если я правильно понимаю ситуацию, то Ваш Логгер находится на уровень ниже вызывающей ф-ии. и на момент ловли исключения стеке есть вызовы этого метода и ниже. Что-бы узнать кто вызывал нужно ловить исключение на уровнях выше FormLoad и обработчика кнопки.
Re[2]: Почему неполный stack trace?
От: MozgC США http://nightcoder.livejournal.com
Дата: 06.10.09 22:57
Оценка:
Здравствуйте, yrtimiD, Вы писали:

D>Если я правильно понимаю ситуацию, то Ваш Логгер находится на уровень ниже вызывающей ф-ии. и на момент ловли исключения стеке есть вызовы этого метода и ниже. Что-бы узнать кто вызывал нужно ловить исключение на уровнях выше FormLoad и обработчика кнопки.


Да, действительно так, stack trace сохраняется с метода в котором сработал catch и вглубь до метода в котором непосредственно произошло исключение. Неудобство в том, что потом по логам нельзя понять кто вызвал метод и это может мешать понять причины исключения. В принципе технических причин которые бы мешали включить в stack trace информацию о том кто нас вызвал — не вижу, в стеке же сохраняется адрес возврата из функции, поэтому видимо причины только в том что решили не перегружать stack trace полным списком.

Встает вопрос "как быть", ведь так хуже по логам разбираться с исключениями. Вижу несколько вариантов:
1) Смириться с тем что stack tracе неполный.
2) Логировать Environment.StackTrace
3) Пересмотреть то как я ловлю и логирую исключения (ссылки на то "как надо" приветствуются, буду благодарен, а щас пока сам пойду искать), при этом обеспечить чтобы по логу и при выводе сообщения об исключении пользователю было понятно во время какой операции возникло исключение.

Кто что думает?
Re[3]: Почему неполный stack trace?
От: Аноним  
Дата: 07.10.09 11:52
Оценка: +3
Здравствуйте, MozgC, Вы писали:

MC>при этом обеспечить чтобы по логу и при выводе сообщения об исключении пользователю было понятно во время какой операции возникло исключение.

Пользователю знать о внутренностях не нужно и гиганский StackTrace будет только раздражать, но для саппорта естественно было бы полезно.

Если исключение совсем неожиданное можно поставить обработчик в AppDomain.UnhandledException там будет полный трейс и будут монитриться все потоки приложения. Если потенциально в этом конкретном месте ожидаемое, то можно добавить Enviroment.StackTrace. Таких мест в принципе должног быть немного если логика не построена на исключениях.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.