В ходе выполнения программы могут возникать динамические ошибки
(ошибки времени выполнения Run Time Errors), которые являются следст-
вием неправильной работы инструкций, процедур, функций или методов
программы. Для обработки динамических ошибок введено понятие ис-
ключения.
Исключение – это результат выполнения некорректного оператора,
вызывающий прерывание или полное прекращение работы программы.
Обработка исключения состоит в нейтрализации вызвавшей его динами-
ческой ошибки.
Исключения могут возникать, например, при попытке деления на ноль
или в результате выполнения вычислений; в случае нехватки памяти; из-за
ошибки преобразования; при попытке обращения к несуществующему
элементу массива и т.д. Независимо от источника ошибки приложение
информируется о его возникновении.
Возникающие при выполнении программы динамические ошибки ав-
томатически преобразовываются средствами Delphi в соответствующие
объекты-исключения. Объект-исключение содержит информацию о типе
ошибки и при возникновении исключения заставляет программу временно
приостановиться. После обработки исключения объект-исключение авто-
матически удаляется.
При работе в среде Delphi при каждой исключительной ситуации среда
перехватывает управление программой. Для отмены реакции среды на
исключительную ситуацию необходимо вызвать опцию Tools/Debugger
Options и на вкладке Language Exceptions отменить переключатель Stop
on Delphi Exceptions.
В Delphi базовым классом для всех исключений служит класс
Exception, от которого порождены многочисленные дочерние типы, соот-
ветствующие часто встречающимся случаям ошибок ввода/вывода, рас-
пределения памяти и т.п.
Часто используются классы исключений, представленные в табл. 4.5.
Таблица 4.5. Наиболее используемые классы исключений
Для обработки исключений введены две конструкции: try..finally
и try..except.
Конструкция try .. finally
Конструкция try..finally состоит из двух блоков (try и finally):
try
//операторы, выполнение которых может вызвать ошибку
finally
//операторы, выполняемые всегда, даже в случае ошибки
end;
Если в любом из операторов блока try возникает исключение, то
управление передается первому оператору блока finally. Если исключе-
ние не возникло, то выполняются все операторы обоих блоков. Конструк-
ция try..finally не обрабатывает исключение, а выполняет действия,
которые должны быть произведены даже в случае возникновения ошибки.
Например,
var f: File;
begin
AssignFile(f, 'Somefile.ext');
try // оператор, в котором возможна ошибка
Reset(f); // работы с файлом
finally
CloseFile(f)
end;
Конструкция try .. except
Конструкция try..except также состоит из двух блоков (try и except):
try
//операторы, выполнение которых может вызвать ошибку
except
//операторы, которые выполняются только в случае ошибки
end;
Конструкция try..except работает так: если в любой из инструкций
блока try возникает исключение, то управление передается первой инст-
рукции блока except, которая ликвидирует исключительную ситуацию и
восстановит работоспособность программы. Если же исключение не воз-
никло, то инструкции блока except не выполняются. Например,
var f: File;
begin
AssignFile(f, 'Somefile.txt');
try //оператор, в котором возможна ошибка
Reset(f); // работы с файлом
except
ShowMessage(‘Ошибка работы с файлом Somefile.txt’);
CloseFile(f)
end
end;
Блок except можно разбить на несколько частей с помощью конст-
рукции on..do, позволяющей анализировать класс исключения для его
более удобной и полной обработки:
try
Оператор1;
Оператор2;
. . .
except
on Идентификатор1: класс исключения do Оператор обработки
ИС этого класса;
on Идентификатор2: класс исключения do Оператор обработки
ИС этого класса;
. . .
else Операторы обработки исключения по умолчанию
end;
При возникновении исключительной ситуации конструкции on..do
просматриваются последовательно, в порядке их описания. Каждый тип
исключительной ситуации, описанный после ключевого слова on, обраба-
тывается именно этим блоком: только то, что предусмотрено в нем, и бу-
дет реакцией на данную ситуацию. Если при этом обработчик родитель-
ского класса стоит перед дочерним, последний никогда не получит управ-
ление. Если класс возникшего исключения не совпадает с проверяемым
классом, то выполняется оператор после слова else. Блок else является
необязательным и может отсутствовать.
Идентификатор – это локальная переменная класса исключения, ко-
торую можно использовать для доступа к объекту возникшего исключения
внутри конструкции on..do. Идентификатор (произвольное имя, заданное
программистом) является необязательным элементом и может отсутство-
вать, при этом не ставится и разделительный знак двоеточия (:).
Стандартная обработка подразумевает вывод на экран сообщения с
указанием типа ошибки, имени модуля и адреса, где она имела место. Од-
нако ее легко переопределить:
try
U:= 220.0;
R:= 0;
I:=U/R;
except
on EZeroDivide do ShowMessage('Короткое замыкание!')
end;
Можно обработать исключение со стандартным сообщением кода
ошибки. Например:
try
Reset(f);
while not EOF(f) do
begin … end; // возможна ошибка работы с файлом
Close(f);
except
on E:EInOutError do ShowMessage(′При выполнении файло-
вой операции’ + #13#10 + ‘возникла ошибка №′
+ IntToStr(E.ErrorCode))
end;
|