Как не потерять StackTrace при обработке исключений в try catch finally?
Вопрос в шапке + "что должно быть в блоках catch и finally?".
Мой ответ: насчёт StackTrace не знаю как его не потерять.
Блок catch, в нём пишем логику обработки исключения. То есть тот процесс, который должен произойти в случае, если произойдёт какой-то фак-ап. Если блок catch не будет найден, то программа завершит процесс аварийно.
Блок finally - в данном блоке код срабатывает, как после успешной обработки логики в try, так и после обработки исключения в catch. Также данный блок можно опустить (finally). В таком случае программа продолжит своё выполнение дальше.
А вот что с StackTrace, как это правильно называется? Трассировка стека ведь правильно будет (из логики вещей). Пожалуйста, расскажите немного об этом.
Ответы (1 шт):
Трассировка стека вызовов - это путь от точки возникновения исключения к точке, где исключение поймано. Когда вы вызываете метод, в стек кладется указатель на точку возврата в текущий метод. Именно по этим указателям и идет сбор данных о цепочке вызванных методов.
Например вам надо обработать исключение и бросить его дальше по стеку, чтобы поймать в каком-нибудь корневом методе, где вы решили ловить и обрабатывать все или почти все исключения, выброшенные из разных концов вашего приложения.
Есть 2 варианта перевыбросить исключение без перегенерации трасстровки.
try
{
// код
}
catch (Exception ex)
{
// обработка исключения
throw;
}
То есть если вы бросите throw ex;, трассировка начнется начиная с точки текущего выброса, а если throw;, то продолжится.
Второй вариант, допустим вы хотите обработать исключение в другом методе, либо в другом блоке кода.
ExceptionDispatchInfo edi = null;
try
{
// код
}
catch (Exception ex)
{
edi = ExceptionDispatchInfo.Capture(ex);
// обработка исключения
}
// еще какой-то код
edi?.Throw(); // тот самый выброс в другом блоке
ExceptionDispatchInfo тоже прекрасно консервирует стек вызовов в исключении.
Исключения не только можно обрабатывать и гасить, можно их наполнять отладочной информацией или другими своими данными. Вы можете сами создать свой класс исключения, унаследовав его от Exception. Когда поработать с исключением нужно, а гасить его не нужно, именно тогда и требуется повторный выброс этого же исключения, без потери трассировки стека, само собой.