Инструментарий Разработчика Facebook был хорошо для всего, для чего я нуждался в нем. Однако стоит упомянуть, что, по крайней мере, по состоянию на сентябрь, документация, образцы и учебные руководства для Инструментария Разработчика Facebook так устарели с его текущим выпуском (Предвыпускная версия 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);
}
Потому что во втором примере вы повторно генерируете исключение из того же метода. Сначала он был выброшен из другого метода, поэтому. В одной области действия метода трассировка стека может быть только одной.
Выполните следующие действия, лучший способ - всегда заключать исключение в новое исключение, чтобы вы могли видеть глубину исключения.
«Если было выполнено повторное генерирование. выпущен в тот же метод (трассировка стека исключений есть только одна информация о номере строки для каждого метода вы никогда не увидите трассировку стека что в методе 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);
}
Я удивлен тем, что так много комментариев не читают мой комментарий !! Я написал в комментарии, что вам, вероятно, следует зарегистрировать это безопасно , есть разные причины, если код верхнего уровня поглощает исключение, а вы этого не делаете. зная, какое и где было сгенерировано исключение, ведение журнала поможет вам пересечь исключение !!!
Если вам не нужно регистрировать исключение, не перехватывайте исключение.