Распечатать страницу

THROW в TRY-конструкции в VFP

« Назад

Команда

THROW [eUserExpression]

создает новый объект-исключение – экземпляр класса Exception, обрабатываемый оператором CATCH внешней или текущей TRY-конструкции.

Параметр eUserExpression может быть любого типа, в том числе и ссылкой на объект; значение параметра устанавливается в свойство UserValue созданного командой THROW объекта-исключения.

Присутствие THROW в CATCH- или FINALLY-блоке прерывает выполнение текущего блока. Управление передается CATCH-блоку внешней TRY-конструкции, если таковая имеется, в противном случае осуществляется выход из текущей TRY-конструкции.

Команда THROW может быть вызвана в любом месте TRY-конструкции, хотя обычно встраивается в один из вложенных CATCH-блоков. Если THROW выполняется CATCH- или FINALLY-блоке, то VFP присваивает переменной VarName опции CATCH TO внешней TRY-конструкции ссылку на объект-исключение, сгенерированный командой THROW.

Пример. Команда THROW генерирует объект-исключение в TRY-конструкции второго уровня и передает управление CATCH-блоку внешней TRY-конструкции. Оператор внутреннего CATCH-блока, следующий за THROW, не выполняется.

store .NULL. to oException1, oException2

try

&& x = Sqrt(–7)

try

    && Попытка извлечь корень из отрицательного числа приведет к ошибке

    x = Sqrt(–5)

catch to oException2

    ? "Оператор до THROW"

    throw CreateObject("ThrowException")

    ? "Оператор после THROW"

endTry

catch to oException1

endTry

if not IsNull(oException1) then

if VarType(oException1.UserValue) = "O" then

    oExcpThrow = oException1.UserValue

    ? oExcpThrow.StackLevel, oException2.ErrorNo, oException2. Message

    ? oException1.StackLevel, oException1.ErrorNo, oExcpThrow.UserValue

else

    ? 1, oException1.ErrorNo, oException1.Message

endif

else

? 'Программа выполнена без ошибок!'

endif

define class ThrowException as Exception

&& Определяем значение свойств StackLevel и UserValue

StackLevel = 2

UserValue = "Обработчик throw-исключения"

&&

procedure Init

    StrToFile("Время возникновения ошибки: " + Ttoc(DateTime( ));

     + Chr(13) + Chr(10), "d:\Errs.log", 1)

endProc

endDefine

Сообщения программы:

Оператор до THROW

61 SQRT( ) argument cannot be negative

2071 Обработчик throw-исключения

Если снять комментарий во внешнем TRY-блоке перед оператором

x = Sqrt(–7)

то при возникновении ошибки управление будет передано сразу CATCH-оператору этого блока, что вызовет следующее сообщение программы:

61 SQRT( ) argument cannot be negative

Таким образом, в приведенном примере THROW позволяет указать уровень TRY-конструкции, обнаружившей ошибку, а также передать время ее возникновения в файл "d:\Errs.log".

Замечание. Описание команды THROW, вызванной вне конструкции, дано в разд. 7.7.

Если параметр eUserExpression задан, то VFP присваивает свойству ErrorNo созданному THROW объекту-исключению значение 2071, соответствующее ошибке User Thrown Error (Error 2071). Если параметр eUserExpression опущен, то VFP использует созданный оператором CATCH объект-исключение, если он существует, в противном случае VFP генерирует новый объект-исключение со значением свойства ErrorNo равным 2071. Так, если в приведенном выше примере употребить

catch to oException2

throw

endTry

catch to oException1

endTry

то после выполнения THROW переменная oException1 будет иметь то же значение, что и переменная oException2, и созданное исключение будет обработано CATCH-блоком внешней TRY-конструкции.

Если нужно сохранить информацию обнаруженного оператором CATCH исключения, то команда THROW употребляется с той же переменной VarName, что и опция CATCH TO, например:

catch to oException2

throw oException2

endTry

catch to oException1

endTry

В этом случае операторы

oExcpThrow = oException1.UserValue

? oExcpThrow.ErrorNo, oExcpThrow. Message

? oException1.ErrorNo

напечатают следующие сообщения:

61 SQRT( ) argument cannot be negative

2071 Обработчик throw-исключения

При таком употреблении THROW свойство UserValue объекта oException1 содержит ссылку на oException2, то есть вместо

oExcpThrow = oException1.UserValue

можно записать

oExcpThrow = oException2

VFP игнорирует команду THROW, если опция CATCH, в которой команда присутствует, употреблена с опцией WHEN eExpression.

Если при оценке eUserExpression команды THROW обнаружена ошибка, то она обрабатывается VFP в обычном порядке.