Использование экземпляров исключений, операторы On..Do в Delphi


За ключевым, словом Except обычно следует список обработчиков исключений состоящий из одного или нескольких операторов On..Do. Общий синтаксис конструкции Try..Except с операторами On..Do следующий:

Try
<операторы, которые могут вызвать исключений>
Except
On <исключение Класса1> Do [<оператор очистки, возможно составной>];
On <исключение класса2> Do [<оператор очистки, возможно составной>];
[Else
<операторы очистки по умолчанию, возможно составные>;] End;

Конструкция Except..On..Do..[Else..]..End похожа по своим действиям на хорошо известный в Pascal оператор Case. В каждом из операторов On..Do экземпляр исключения проверяется на совместимость с типом указанного класса исключения или его потомка. Если совместимость обнаруживается, то выполняется соответствующий оператор очистки, который может быть и составным (Begin..End). Если совместимость не обнаруживается, то выполняются операторы очистки, предусмотренные по умолчанию в разделе Else, a при их отсутствии продолжается поиск обработчика исключения во внешних конструкциях Тrу или далее.

try
divCircle;
except
on EConvertError do showmessage(‘Ошибка преобразования типа’);
on EZeroDivide do showmessage (‘Деление на нуль’);
end;

Если в операторе On..Do не указывать оператор очистки, то реализуется вариант «тихого» исключения — исключение уничтожается, однако сообщения нет. Можно использовать такую конструкцию для несущественных ошибок.
On EConvertError Do; // Уничтожается исключение без вывода сообщения о нем

Использование экземпляров исключений

Одна из причин использования экземпляров исключений в обработке исключений — возможность передачи информации о состоянии ошибки из места, где ошибка произошла, в обработчик ошибок с целью получения дополнительной информации об ошибке. Это может быть — адрес возникновения ошибки, класс объекта или модуль, в котором она произошла и т.п. Есть несколько вариантов доступа к экземпляру исключения и его использования.

А) Для передачи данных, хранящихся в экземпляре объекта исключения. следует использовать следующий синтаксис конструкции Try..Except:

Try
<операторы, которые могут возбуждать исключений Except
On <идентификатор>: <имя класса исключения> Do
<оператор, который использует <идентификатор> для доступа к полям экземпляра исключения указанного типа>; End;

С помощью <идентификатора> предоставляется доступ к экземпляру класса исключения, который был уже где-то создан и уже помещен в стек, и где-то будет уничтожен. Новая переменная при этом не создается, а дается только имя уже существующему объекту (экземпляру исключения) для работы с ним.

«Отметим также, что не требуется предварительное объявление типа данных <идентификатора>. Его тип и значение определяются по ходу выполнения программы.

Var L1,L2: Integer; R: Real;
Try
R:=I1/I2; // Выполняется деление одного числа на другое
Except
On E: EZeroDivide Do
ShowMessage(‘Клacc: ‘+E.CIassName+#10#13+’Oшибка ‘+E.Message); End;

Вместо исключения EZeroDivide можно с не меньшим успехом использовать базовое исключение Exception. Благодаря полиморфизму вся предусмотренная для пользователя информация будет также определена и выведена.

Вместо стандартного (англоязычного) сообщения об ошибке можно подставить и русскоязычное.

Используя идентификатор исключения, можно вместо нескольких операторов On..Do применить так называемую конструкцию с «динамической проверкой». Ее синтаксическая конструкция имеет следующий вид:

On E: Exception Do Begin
If E Is EConvertError Then <oпepaтop>; // Проверка других типов исключений
If E Is EIntToStr Then <оператор> Else Raise; End;

б) Для доступа к экземпляру исключения можно использовать, чаще
всего в разделе Else конструкции Try..Except, следующую функцию:
ExceptObject: TObject; — Возвращает экземпляр ошибки.

On EConvertError Do
ShowMessage(EConvertError(ExceptObject).Message);

в) Для вывода информации о классе компонента, в котором возникло исключение, а также о классе возникшего исключения можно использовать конструкцию оператора On..Do:

Var S1,S2: String;
On E: EZeroDivide Do Begin
S1:=Self.ClassName;// Компонент, в котором возникла ошибка
S2:=E.CIassName;// Класс возбужденного исключения
MessageDlg(S1+#10#13+S2, mtError, [mbOK], 0);
End;

г) Можно определить адрес возникновения ошибки с помощью функции:

ExceptAddr: Pointer; — Возвращает адрес возникновения ошибки.
On E: EZeroDivide Do
ShowMessage(E.Message+#10#13+Fonnat(‘%p’, [ExceptAddr]));


Комментарии запрещены.




Статистика