Библиотека программиста

«Очень важно не прерывать вопросов. Любопытство имеет свое право на существование»

Альберт Эйнштейн

Главная страница > Язык Object Pascal > 33. Дополнительные возможности обработки ИС

33. Дополнительные возможности обработки ИС

Вызов исключительной ситуации.

В процедуре C из примера мы уже могли видеть, как должна поступать программа при обнаружении состояния ошибки - она вызывает (генерирует) исключительную ситуацию:

raise ESampleError.Create('Error!');

После ключевого слова raise следует код, аналогичный тому, что используется для создания нового экземпляра класса. Действительно, в момент вызова исключительной ситуации создается экземпляр указанного класса. Данный экземпляр существует до момента окончания обработки исключительной ситуации и затем автоматически уничтожается. Вся информация, которую нужно сообщить в обработчик ошибки, передается в объект через его конструктор в момент создания.

Почти все существующие классы исключительных ситуаций являются наследниками базового класса Exception и не содержат новых свойств или методов. Класс Exception имеет несколько конструкторов (а именно 8), какой из них конкретно использовать - зависит от задачи. Конструкторы, в имени которых присутствует Fmt, например, CreateFmtHelp, позволяют включать в текст сообщения значения переменных. Впрочем, сделать это можно и другими способами.

Приведем пример использования конструктора с форматированием. Функция StrToIntRange преобразует число из символьного формата во внутренний с контролем диапазона:

Function StrToIntRange(const S: string; Min, Max: Longint): Longint;

Begin

Result := StrToInt(S);

if (Result < Min) or (Result > Max) then

raise ERangeError.CreateFmt('%d вне диапазона %d..%d',

[Result, Min, Max]);

End;

Объекты ИС создаются с помощью конструкторов, а уничтожаются автоматически после обработки ИС и для них не нужно вызывать деструкторов.

Исключительные ситуации не могут обрабатываться в секции инициализации, так как для их обработки необходимо выполнение секции инициализации модуля SysUtils. Если ИС возникает в секции инициализации, то это всегда приводит к завершению приложения.

Доступ к экземпляру объекта exception.

До сих пор мы рассматривали механизмы защиты кода и ресурсов, логику работы программы в исключительной ситуации. Теперь нужно немного разобраться с тем, как же обрабатывать возникшую ошибку. А точнее, как получить дополнительную информацию о коде ошибки, текст сообщения и т.п.

Как уже говорилось, при вызове (raise) ИС автоматически создается экземпляр соответствующего класса, который и содержит информацию об ошибке. Весь вопрос в том, как в обработчике данной ситуации получить доступ к этому объекту.

Рассмотрим модифицированную процедуру A в нашем примере:

procedure NewA;

begin

writeln('Enter A');

try

writeln('Enter A''s try block');

B;

writeln('After B call');

except

on ExLocal : ESampleError do writeln(ExLocal.Message);

on ESomethingElse do

writeln('Inside A''s ESomethingElse handler');

end;

writeln('Exit A');

end;

Здесь все изменения внесены в строку

on ExLocal: ESampleError do writeln(ExLocal.Message);

Пример демонстрирует еще одно новшество в языке Object Pascal - создание локальной переменной. В нашем примере локальной переменной является ExLocal - это тот самый экземпляр класса ESampleError, который был создан в процедуре C в момент вызова ИС. Переменная ExLocal доступна только внутри блока do. Свойство Message объекта ExLocal содержит сообщение, которое было передано в конструктор Create в процедуре C.

Экземпляр класса ИС существует только внутри оператора on и автоматически уничтожается по завершению этого оператора. В Delphi 6, тем не менее, его жизнь можно продлить с помощью процедуры AcquireExceptionObject, но в этом случае программист должен сам позаботиться об уничтожении ИС с помощью процедуры ReleaseExceptionObject.

В модуле SysUtils есть также процедура

Procedure ShowException(ExceptObject: TObject; ExceptAddr: Pointer);

Она выводит сообщение об ИС и адрес точки программы, в которой случилась ИС. Этот адрес можно использовать в меню Search/Find Error для поиска соответствующей строки программы. В качестве фактических параметров при вызове ShowException удобно использовать функции ExceptObject и ExceptAddr. Функция ExceptObject возвращает имя класса последней ИС (например, EMyException), а ExceptAddr – адрес точки программы, в которой возникла ИС. Процедуру ShowException можно использовать в блоке else оператора try…except, где класс ИС не известен.

Другая возможность для определения места возникновения ИС – использование процедуры

Procedure Assert(expression:boolean; [ const msg:string ] );

Если expression=true, то эта процедура ничего не делает. В противном случае создается ИС EAssertionFailed. Фокус в том, что обработчик этой ИС возвращает точные координаты места ИС, а именно вызова Assert: полное имя файла и номер строки программы, что весьма полезно для целей отладки.

Пример ее использования:

Procedure C;

Begin

if ErrorCondition then Assert(false,'Error in C');

End;

Procedure A;

Begin

try

writeln('Enter A''s try block');

B;

writeln('After B call');

except

on EAssertionFailed do writeln('Inside A''s EAssertion handler');

end;

End;

Ценно также то, что с помощью директивы компилятора {$ASSERTIONS ON/OFF} возникновение обсуждаемой ИС можно цетрализованно разрешить или запретить.

Еще одно исключение – EAbort – является “скрытым”. Используйте его тогда, когда хотите прервать тот или иной процесс с условием, что пользователь программы не должен видеть сообщения об ошибке. Отличие EAbort от других ИС состоит в том, что в этом случае не выводится окно с сообщением о возникшей ИС. Пример использования:

. . .

if ErrorCondition then

begin {СоздаемсамостоятельноИС}

writeln('Raising exception in C');

raise EAbort.Create('Condition 1');

end;

. . .

except

on LocalAbort : EAbort do

begin

writeln('Inside A''s EAbort handler' + LocalAbort.Message);

end;

. . .

end;

Еще один способ вызова этой ИС – просто вызов процедуры Abort.





<< Предыдущая статья
«32. Примеры обработки исключительных ситуаций»
Следующая статья >>
34. Предопределенные обработчики исключительных ситуаций