Для реакции на конкретный тип ситуации применяется блок try..except. Синтаксис его следующий:
try
<Оператор>
<Оператор>
...
except
on EExceptionl do < Оператор обработки ИС типа EExceptionl >;
on EException2 do < Оператор >;
...
else { }
<0ператор> {обработчик прочих ИС}
end;
Выполнение блока начинается с секции try. При отсутствии исключительных ситуаций только она и выполняется. Секция except получает управление в случае возникновения ИС. После обработки происходит выход из защищенного блока, и управление обратно в секцию try не передается; выполняются операторы, стоящие после end.
Если вы хотите обработать любую ИС одинаково, независимо от ее класса, вы можете писать код прямо между операторами except и end. Но если обработка отличается, здесь можно применять набор директив on..do, определяющих реакцию приложения на определенную ситуацию. Каждая директива связывает ситуацию (on...), заданную своим именем класса, с группой операторов (do...).
U:= 220.0;
R:= 0;
try
I:= U / R;
except
on EZeroDivide do MessageBox('Короткое замыкание!');
|
|
end;
В этом примере замена if..then на try..except, может быть, не дала очевидной экономии кода. Однако если при решении, допустим, вычислительной задачи проверять на возможное деление на ноль приходится не один, а множество раз, то выигрыш от нового подхода неоспорим — достаточно одного блока try..except на все вычисления.
При возникновении ИС директивы просматриваются последовательно, в порядке их описания. Каждый тип исключительной ситуации, описанный после ключевого слова on, обрабатывается именно этим блоком: только то, что предусмотрено в нем, и будет являться реакцией на данную ситуацию.
Если при этом обработчик родительского класса стоит перед дочерним, последний никогда не получит управления.
try
i:=l;j:=0;
k:=i div j;
...
except
on EIntError do ShowMessage('IntError');
on EDivByZero do ShowMessage('DivByZero');
end;
В этом примере, хотя в действительности будет иметь место деление на ноль (EDivByZero), вы увидите сообщение, соответствующее родительскому классу EintError. Но стоит поменять две конструкции on..do местами, и все придет в норму.
Если возникла ситуация, не определенная ни в одной из директив, выполняются те операторы, которые стоят после else. Если и их нет, то ИС считается не обработанной и будет передана на следующий уровень обработки. Этим следующим уровнем может быть другой оператор try..except, который содержит в себе данный блок.