Хотя вложение try...except
в try...finally
(или наоборот) напрямую отвечает на вопрос, я хотел бы отметить, что оригинальный вопрос, независимо от того, какой язык вы используете, смешивает проблемы обработки ошибок и ресурсовуправление.Try...except
и try...finally
ужасны.Они отвлекают вас от того, что делает ваш код.Лучший подход состоит в том, чтобы выделить обработку ошибок в отдельный метод:
procedure Read(Connection: TDBConnection);
begin
try
//Read DB
except
//Handle Exception
end;
end;
procedure ReadRecord;
begin
DBConnection.Open;
Read(DBConnection);
DBConnection.Close;
end;
Теперь ваша обработка ошибок является автономной и может быть проигнорирована, чтобы вы могли сосредоточить свое внимание на happy path .
Подождите!А как насчет open
и close
?Что если они возбуждают исключения?
Простой.Оберните эти операции в try ... кроме функций и обработайте их.Это не должно быть необходимо.Если используемая вами библиотека БД чего-то стоит, исключение в open
или close
не оставит соединение в неизвестном состоянии.С другой стороны, существуют исключения для вещей, которых вы не ожидаете.
Та же самая техника может использоваться с любым ресурсом: создание объекта, доступ к файлу и т. Д. Когда тело вашей функции гарантированно не будет вызыватьсяисключение try...finally
не нужно.
Конечно, есть издержки вызова функций, но в большинстве случаев они незначительны, и ваши функции обработки ошибок должны быть достаточно малы, чтобы компилятор мог их встроить.