Технология обработки исключений в Delphi
Уровни обработки исключительных ситуаций
Программы, написанные на Delphi, имеют два уровня обработки исключений. Библиотека визуальных компонентов VCL имеет свой уровень обработки исключений, с которым в большинстве случаев и встречаются пользователи. Чаще всего исключения на этом уровне, так или иначе, обрабатываются, и далее пользователь может продолжить работу с программой. На этом уровне программистам предоставляется возможность включить в программу свои обработчики исключений. Возможные варианты обработчиков выше были уже рассмотрены.
Второй уровень обработки исключений обычно обрабатывает исключения нижнего уровня, возникающие при загрузке или выгрузке приложения или во время выполнения кода обработки VCL. Как правило, восстановление нормальной работы программы после этого невозможно. Пользователь информируется о случившемся исключении, и программа выгружается из памяти. В худших случаях возможно «зависание» системы. Обработчик низкого уровня находится в RTL (Run-Time Library) — библиотеке времени выполнения.
Следует иметь в виду, что среда Delphi перехватывает все возникающие исключительные ситуации библиотеки VCL. Поэтому для отладки собственных обработчиков необходимо запускать приложения либо непосредственно из Windows, либо отключить перехватчик Delphi. Для отключения перехватчика следует:
• Из главного меню Delphi выполнить команды:
ToolsVDebugger Options…
• В открывшемся окне Debugger Options на странице Language Exceptions следует отключить флажок Stop on Delphi Exceptions.
Механизм обработки исключительных ситуаций
Говоря о технологии обработки исключительных ситуаций, следует иметь в виду возможности, которые имеются на уровне библиотеки VCL.
В общем случае механизм обработки исключительных ситуаций следующий:
• Если в программе предусмотрена конструкция Try..Except или Try..Finally, то в случае конструкции Try..Except исключение будет в ней обработано.
Если в конструкции дополнительно используется оператор Raise, то обработка исключения продолжится за пределами конструкции Try..Except;
• в случае конструкции Try..Finally захваченные ресурсы будут освобождены, однако обработка исключения продолжится за пределами конструкции Try..Finally.
• Если в программе не предусмотрена обработка исключения с помощью блоков Try или исключение вышло за пределы блока Try..Except, то у объекта Application вызывается метод HandleException, который встроен в раздел Except многих обработчиков событий и метода WndProc.
Если исключение передается в метод HandleException, то последовательность его обработки следующая:
— Исключение первоначально проверяется на совместимость по присвоению с классом Exception. Если оно не совместимо с классом Exception, например, вследствие возникновения аппаратной ошибки, то работа процедуры заканчивается выводом сообщения, включающего информацию об ошибке и ее адресе.
— Если исключение совместимо с классом Exception, то оно вновь проверяется на совместимость по присвоению, но уже с классом EAbort. Если оно совместимо с классом EAbort, то обработка сообщения заканчивается без вывода всяких сообщений.
— Если исключение не совместимо по присвоению с классом EAbort, то первоначально проверяется содержимое поля FOnException (фактически проверяет наличие обработчика у события OnException) и, если оно не пусто, то вызывает обработчик этого события, которому передается объект, вызвавший исключение и экземпляр исключения.
В этом обработчике имеется возможность перехватить и переопределить стандартную обработку всех или части исключительных ситуаций.
— Если поле FOnException пусто (Nil), то будет вызван обработчик по умолчанию, который, как уже отмечалось ранее, заключается в вызове метода ShowException, отображающего окно диалога с именем приложения в заголовке и сообщением об ошибке и адресе его возникновения.
Обработчики исключений
Как указывалось выше, помимо конструкций Try, есть еще несколько приемов обработки исключений. Они включают создание новых классов исключений: Raise Exception.Create(‘Out of memory.’);
использование события OnException глобального объекта Application и применение ряда специальных процедур: OutOfMemoryError;
Объявление новых классов исключений
Для объявления новой исключительной ситуации следует объявить новый класс исключений. Как правило, новый класс должен:
• или предоставлять более полную информацию об ошибке;
• или обслуживать совершенно новую категорию ошибочных ситуаций.
Синтаксис для объявления класса исключений следующий:
Туре <имя класса>=Сlass{<имя родительского класса исключения>)
<поля> End;
— конструкция позволяет объявить новые поля, причем обычно они описываются в разделе Public.
type
EMyException = class(Exception)
private
fparam: integer;
public
property param : integer read fparam;
constructor MyCreate(const Msg: string;cparam : integer);
end;
constructor EMyException.MyCreate(const Msg: string; cparam: integer);
begin
inherited create(Msg);
fparam:=cparam;
end;
возбудить:
raise EMyException.MyCreate(‘моё исключение’,p);