Сохранение исходного StackTrace/LineNumbers в Исключениях.NET

Инструментарий Разработчика Facebook был хорошо для всего, для чего я нуждался в нем. Однако стоит упомянуть, что, по крайней мере, по состоянию на сентябрь, документация, образцы и учебные руководства для Инструментария Разработчика Facebook так устарели с его текущим выпуском (Предвыпускная версия 2), что это могло бы быть минное поле для нового разработчика.

15
задан Jon Seigel 4 April 2010 в 17:36
поделиться

2 ответа

Я не уверен, относится ли это ограничение к языку C #, CLI или их реализации Microsoft, но ваш второй пример - это случай, когда явный вызов Exception.InternalPreserveStackTrace требуется, как описано в следующем сообщении.Поскольку этот метод является внутренним , он обычно вызывается посредством отражения. Связанные с этим проблемы с производительностью можно почти полностью решить, создав для вызова Action , как показано в конце этого ответа.

Ссылка: Повторное генерирование исключений и сохранение полной трассировки стека вызовов

Редактировать: После повторной проверки ECMA-335 Раздел I §12.4.2 (обработка исключений) и Раздел III §4.24 (повторный вызов), I. теперь верьте, что поведение, которое вы видите, является семантической ошибкой в ​​CLR (реализация Microsoft CLI). Единственная конкретная ссылка на поведение - «A rethrow не изменяет трассировку стека в объекте». В случае, описанном здесь, повторное генерирование фактически изменяет трассировку стека, заставляя PreserveStackTrace взломать обходной путь для известного недостатка CLR.

static void LongFaultyMethod() 
{ 
    try 
    { 
        int x = 20; 
        int y = x / (x - 20); 
    } 
    catch (Exception ex) 
    { 
        PreserveStackTrace(ex); // <-- add this line
        throw; 
    } 
} 

PreserveStackTrace вот оптимизация из той записи в блоге:

private static readonly Action<Exception> _internalPreserveStackTrace =
    (Action<Exception>)Delegate.CreateDelegate(
        typeof(Action<Exception>),
        typeof(Exception).GetMethod(
            "InternalPreserveStackTrace",
            BindingFlags.Instance | BindingFlags.NonPublic));

public static void PreserveStackTrace(Exception e)
{
    _internalPreserveStackTrace(e);
}
17
ответ дан 1 December 2019 в 03:52
поделиться

Потому что во втором примере вы повторно генерируете исключение из того же метода. Сначала он был выброшен из другого метода, поэтому. В одной области действия метода трассировка стека может быть только одной.

Выполните следующие действия, лучший способ - всегда заключать исключение в новое исключение, чтобы вы могли видеть глубину исключения.

«Если было выполнено повторное генерирование. выпущен в тот же метод (трассировка стека исключений есть только одна информация о номере строки для каждого метода вы никогда не увидите трассировку стека что в методе A, в строке номер 2 было выбрано исключение, а затем в том же Метод А, он был переброшен с линии номер 17, он будет содержать только последний номер строки, откуда было исключение rethrown "

try        
{            
   int x = 20;            
   int y = x / (x - 20);        
}        
catch (Exception ex)        
{            
   // do something here.. like log or something
   throw new Exception("Internal Exception", ex);        
}

Я удивлен тем, что так много комментариев не читают мой комментарий !! Я написал в комментарии, что вам, вероятно, следует зарегистрировать это безопасно , есть разные причины, если код верхнего уровня поглощает исключение, а вы этого не делаете. зная, какое и где было сгенерировано исключение, ведение журнала поможет вам пересечь исключение !!!

Если вам не нужно регистрировать исключение, не перехватывайте исключение.

2
ответ дан 1 December 2019 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: