Обработка исключений: различия между версиями

[отпатрулированная версия][отпатрулированная версия]
Содержимое удалено Содержимое добавлено
Строка 36:
=== Неструктурная обработка исключений ===
Неструктурная обработка исключений реализуется в виде механизма регистрации [[Функция (программирование)|функций]] или команд-обработчиков для каждого возможного [[Тип данных|типа]] исключения. [[Язык программирования]] или его системные [[Библиотека (программирование)|библиотеки]] предоставляют программисту как минимум две стандартные процедуры: регистрации обработчика и разрегистрации обработчика. Вызов первой из них «привязывает» обработчик к определённому исключению, вызов второй — отменяет эту «привязку». Если исключение происходит, выполнение основного кода программы немедленно прерывается и начинается выполнение обработчика. По завершении обработчика управление передаётся либо в некоторую наперёд заданную точку программы, либо обратно в точку возникновения исключения (в зависимости от заданного способа обработки — с возвратом или без). Независимо от того, какая часть программы в данный момент выполняется, на определённое исключение всегда реагирует последний зарегистрированный для него обработчик. В некоторых языках зарегистрированный обработчик сохраняет силу только в пределах текущего блока кода (процедуры, функции), тогда процедура разрегистрации не требуется. Ниже показан условный фрагмент кода программы с неструктурной обработкой исключений:
<sourcepre>
УстановитьОбработчик(ОшибкаБД, ПерейтиНа ОшБД)
// На исключение "ОшибкаБД" установлен обработчик - команда "ПерейтиНа ОшБД"
Строка 47:
СнятьОбработчик(ОшибкаБД)
// Обработчик снят
</sourcepre>
 
Неструктурная обработка — практически единственный вариант для обработки асинхронных исключений, но для синхронных исключений она неудобна: приходится часто вызывать команды установки/снятия обработчиков, всегда остаётся опасность нарушить логику работы программы, пропустив регистрацию или разрегистрацию обработчика.
Строка 54:
{{не путать|Структурированная обработка исключений}}
Структурная обработка исключений требует обязательной поддержки со стороны [[Язык программирования|языка программирования]] — наличия специальных [[Синтаксис (программирование)|синтаксических]] конструкций. Такая конструкция содержит [[Блок (программирование)|блок]] контролируемого кода и обработчик (обработчики) исключений. Наиболее общий вид такой конструкции (условный):
<codepre>
НачалоБлока
... // Контролируемый код
Строка 67:
... // Код обработки ранее не обработанных исключений
КонецБлока
</codepre>
 
Здесь «НачалоБлока» и «КонецБлока» — [[Зарезервированное слово|ключевые слова]], которые ограничивают блок контролируемого кода, а «Обработчик» — начало блока обработки соответствующего исключения. Если внутри блока, от начала до первого обработчика, произойдёт исключение, то произойдёт переход на обработчик, написанный для него, после чего весь блок завершится и исполнение будет продолжено со следующей за ним команды. В некоторых языках нет специальных ключевых слов для ограничения блока контролируемого кода, вместо этого обработчик (обработчики) исключений могут быть встроены в некоторые или во все синтаксические конструкции, объединяющие несколько операторов. Так, например, в языке Ада любой составной оператор (begin — end) может содержать обработчик исключений.
Строка 79:
=== Блоки с гарантированным завершением ===
Помимо блоков контролируемого кода для обработки исключений, языки программирования могут поддерживать блоки с гарантированным завершением. Их использование оказывается удобным тогда, когда в некотором блоке кода, независимо от того, произошли ли какие-то ошибки, необходимо перед его завершением выполнить определённые действия. Простейший пример: если в процедуре динамически создаётся какой-то локальный объект в памяти, то перед выходом из этой процедуры объект должен быть уничтожен (чтобы избежать утечки памяти), независимо от того, произошли после его создания ошибки или нет. Такая возможность реализуется блоками кода вида:
<codepre>
НачалоБлока
... // Основной код
Строка 85:
... // Код завершения
КонецБлока
</codepre>
Заключённые между ключевыми словами «НачалоБлока» и «Завершение» операторы (основной код) выполняются последовательно. Если при их выполнении не возникает исключений, то затем выполняются операторы между ключевыми словами «Завершение» и «КонецБлока» (код завершения). Если же при выполнении основного кода возникает исключение (любое), то сразу же выполняется код завершения, после чего весь блок завершается, а возникшее исключение продолжает существовать и распространяться до тех пор, пока его не перехватит какой-либо блок обработки исключений более высокого уровня.