ПрограммированиеVB.NET разработчик, Backend разработчик

Как реализуется обработка и проброс (rethrow) исключений в Visual Basic? Какие тонкости существуют между оператором Throw и Throw ex, и чем опасен неправильный повторный выброс исключения?

Проходите собеседования с ИИ помощником Hintsage

Ответ

В Visual Basic для обработки исключений используется блок Try...Catch...Finally. Чтобы пробросить исключение после перехвата — т.е. передать его дальше по стеку вызовов — применяется оператор Throw или Throw ex.

Различия:

  • Throw (без параметра) повторно выбрасывает текущее исключение, сохраняя исходный стек вызовов (Call Stack).
  • Throw ex выбрасывает объект исключения, но сбрасывает стек вызовов — информацию о месте реального возникновения проблемы.

Рекомендуется использовать Throw без параметров для корректного проброса исключения, если оно не было модифицировано.

Пример корректного проброса:

Try DangerousOperation() Catch ex As Exception ' Логирование... Throw ' сохраняется стек вызовов End Try

Некорректный способ:

Try DangerousOperation() Catch ex As Exception Throw ex ' Стек вызовов сброшен, диагностика затруднена End Try

Вопрос с подвохом

Что случится со стеком вызовов, если вы используете Throw ex вместо Throw?

При использовании Throw без параметра сохраняется исходный стек вызовов — тот, где возникло исключение. Если использовать Throw ex, то стек начинается с текущей строки, а исходное место возникновения теряется. Это усложняет отладку, поскольку вы не увидите, в какой части кода возникла проблема.

Примеры реальных ошибок из-за незнания тонкостей темы


История

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


История

Внутри слоя доступа к данным использовали Throw для проброса SqlException, но в некоторых случаях инструмент автоформатирования кода автоматически заменил его на Throw ex. Это сломало систему автоматического извлечения данных из логов и увеличило время отклика на инциденты.


История

Попытка модифицировать объект Exception и пробросить его через Throw без параметра привела к тому, что изменения не отразились в логах — помогло только явное создание нового объекта исключения с сохранением исходного как InnerException.