В 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.