Visual FoxPro предоставляет несколько обработчиков ошибок, которые вы можете использования для обнаружения и обработок ошибок в коде программы.

Caution noteПредупреждение

Использование операторов TRY...CATCH в процедурном коде метода класса, чье определение не имеет события Error или в программном коде метода может влиять на существующий код и сделать невозможным совместимость назад, для более ранних версий Visual FoxPro.

В приведенной ниже таблицы сведены приоритеты обработчиков ошибок.

 
Когда присутствует только приведенный ниже обработчик ошибок Приоритет обрабочика ошибок

Обработчик отсутствует или существующий не в состоянии обработать ошибку

Системное сообщение об ошибке Visual FoxPro

Команда ON ERROR

ON ERROR имеет преимущество, пока не вызван другой обработчик ON ERROR или пока не восстановлено системное сообщение об ошибке Visual FoxPro.

В противном случае, Visual FoxPro отобразит системное сообщение об ошибке.

Команда TRY...CATCH...FINALLY

TRY...CATCH...FINALLY имеет преимущество, когда ошибка происходит в блоке TRY.

В противном случае, Visual FoxPro отобразит системное сообщение об ошибке.

Событие Error или метод

Error имеет преимущество, когда ошибка происходит в коде метода объекта.

В противном случае, Visual FoxPro отобразит системное сообщение об ошибке.

Команда TRY...CATCH...FINALLY и команда ON ERROR

TRY...CATCH...FINALLY имеет преимущество, когда ошибка происходит в блоке TRY.

ON ERROR имеет преимущество, когда:

  • Ошибка происходит вне блока TRY.

  • Ошибка происходит в блоке CATCH.

  • Ошибка происходит в блоке FINALLY.

В противном случае, Visual FoxPro отобразит системное сообщение об ошибке.

Событие Error или ON ERROR

Error имеет преимущество, когда ошибка происходит в коде метода объекта.

ON ERROR имеет преимущество, когда:

  • Ошибка происходит вне определения класса.

  • Ошибка проимходит внутри определения класса, но вне кода метода. Ошибка определяется в точке инициализации объекта.

В противном случае, Visual FoxPro отобразит системное сообщение об ошибке.

Команда TRY...CATCH...FINALLY или событие Error

TRY...CATCH...FINALLY имеет преимущество, когда:

  • Ошибка произошла в блоке TRY вне определения класса.

  • Ошибка произошла в коде метода объекта и он находится внутри блока TRY block.

  • Ошибка имеет начало в определении класса вне кода метода, но наступила в блоке TRY вне определения класса.

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

Error имеет преимущество, когда:

  • Ошибка произошла внутри кода метода, но вне блока TRY.

  • Ошибка произошла в коде метода объекта, а метод был вызван напрямую из другого метода, независимо от того, где появился вызов метода - внутри или извне блока TRY.

    NoteЗамечание

    Если вызов метода осуществлен в блоке TRY, и не существует ближайщего события Error или не существует кода метода для этого объекта, Visual FoxPro будет искать код для события Error, наследуемый из родительского класса или иного класса вверх по иерархии класса. Если не существует кода для Error в иерархии класса, Visual FoxPro будет искать блок CATCH, соответствующий блоку TRY, из которого был вызван метод.

В противном случае Visual FoxPro отобразит системное сообщение об ошибке.

Резюме об обработке ошибок в коде метода объекта

Для ошибок, случившихся в коде метода объекта, порядок приоритетов для обработчиков ошибок определяется так, как представлено ниже:

  • Непосредственный TRY...CATCH, если он существует, в том же методе, в котором произошла ошибка. Это применяется и к внешним процедурам, которые вызываются в методе.

  • Событие Error объекта, если оно существует.

  • TRY...CATCH следующего уровня в цепочке вызовом или в методе уровнем выше.

  • Процедура ON ERROR, если она существует.

  • Системное сообщение об ошибке Visual FoxPro.

Для получения более подробной информации о приоритетах обработки ошибок внутри структуры TRY...CATCH...FINALLY смотрите описание Приоритет обработки ошибки в структурах TRY...CATCH...FINALLY - ниже в этом же топике. Для получения более подробной информации о приоритетах обработки ошибок в классах и объектах смотрите описание Приоритет обработки ошибки в классах и объектах - ниже в этом же топике.

Приоритет обработки ошибки в структурах TRY...CATCH...FINALLY

В приведенной ниже таблице сведены последовательности действий при обработке ошибок или команд THROW в блоке TRY структуры TRY...CATCH...FINALLY.

 
Когда существует указанный ниже обработчик ошибок и ошибка происходит в первом указанном блоке кода Последовательность действий

Не существует обработчика ошибок

Отображается соответствующее системное сообщение об ошибке Visual FoxPro.

Блок кода CATCH

Ошибку обрабатывает блокCATCH.

Блок кода CATCH, блок кода FINALLY

Блок кода CATCH обрабатывает ошибку, затем исполняется код блока FINALLY.

Исполняется внутренний блок кода CATCH, затем внутренний блок кода FINALLY внешнего блока структуры TRY.

Внутренний блок кода CATCH обрабатывает ошибку. Внутренний блок кода FINALLY исполняется. Внешний блок кода FINALLY исполняется.

Если не существует внутренного блока кода CATCH, то исполняется код блока FINALLY, внешний блок кода CATCH обрабатывает ошибку и исполняется внешний блок кода FINALLY.

Код блока CATCH, код блока FINALLY, команда ON ERROR

Блок кода CATCH обрабатывает ошибку. Затем исполняется кода блока FINALLY. Затем исполняется команда ON ERROR.

Если не существует блока кода CATCH, исполняется блок кода FINALLY, а ошибку обрабатывает команда ON ERROR.

Блок кода CATCH, блок кода FINALLY и блок кода события Error.

Код блока CATCH обрабатывает ошибку. Затем исполняется код блока FINALLY. Затем исполняется код события Error.

Если не существует блока CATCH, то исполняется код блока FINALLY и затем событие Error обрабатывает ошибку.

Для получения более подробной инфорамции о том, как структуры TRY...CATCH...FINALLY обрабатывают ошибки смотрите описание Структурированная обработка ошибок.

Приоритеты обработки ошибка в классах и объектах

Когда ошибка происходит в коде метода объекта, а метод вызван непосредственно или из блока TRY структуры TRY...CATCH...FINALLY, Visual FoxPro следует процедуре обработки ошибка для этого конкретного объекта. Такой протокол позволяет вас поддерживать инкапсуляцию и управлять вашими компонентами. Обычно, событие Error объекта, если оно существует, имеет преимущество над прочими обработчиками ошибок, если код метода объекта содержит свою собственную структуру TRY...CATCH...FINALLY structure.

Для получения более подробной информации об обработке ошибок для классов и объектов смотрите описание Обработка ошибок класса и объекта.

Примеры приоритетов обработки ошибок для кода метода объекта

В приведенном ниже примере, в котором класс содержит событие Error, код создает экземлпяр объекта из пользовательского класса с именем MyObjectClass, в котором определены два метода, содержащих блоки TRY...CATCH, один метод, который содержит ошибку и событие Error. Объект далее вызывает два определенных в классе метода.

Блок TRY в Method1 содержит вызов пользовательского метода RaiseError, которые генерирует ошибку. Однако, блок CATCH в Method1 не обрабатывает эту ошибку; вместо этого, код события Error класса обрабатывает эту ошибку и отображает указанное сообщение. Если событие Error не существует, блок CATCH в Method1 смог бы отобразит указанное сообщение.

В противополжность этому, когда ошибка происходит до блока TRY в Method2, событие Error обрабатывает эту ошибку отображением указанного сообщения. Когда в блоке TRY в Method2 происходит вторая ошибка, блок CATCH обрабатывает вторую ошибку и отображает указанное сообшение.

 CopyCode imageСкопировать код
CLEAR
oMyObject = CREATEOBJECT("MyClass")
oMyObject.Method1()
?
oMyObject.Method2()

DEFINE CLASS MyClass AS Custom
   PROCEDURE Method1
      ? "Method1"
      TRY
         ? "Вызов метода RaiseError в блоке TRY для Method1."
         This.RaiseError()
      CATCH
         ? "Работает блок CATCH для Method1. Ошибка поймана."
      ENDTRY
   ENDPROC

   PROCEDURE Method2
      ? "Method2"
      ? "Ошибка гененируется до блока TRY в Method2."
      ERROR 1
      TRY
         ? "Генерируется ошибка в блоке TRY в Method2."
         ERROR 1 
      CATCH
         ? "Работает блок CATCH метода Method2. Ошибка поймана."
      ENDTRY
   ENDPROC

   PROCEDURE RaiseError
      ? "Работает метод RaiseError. Генерируется ошибка."
      ERROR 1
   ENDPROC

   PROCEDURE Error(t1,t2,t3)
      ? "Сработало событие Error объекта, созданного из класса MyObjectClass."
   ENDPROC
ENDDEFINE

В приведенном ниже примере, в котором класс не содержит события Error, код создает экземлпяр объекта из пользовательского класса с именем MyClass, в котором определены два метода: первый из них содержит блок TRY...CATCH, тогда как второй такого блока не содержит.

Блок TRY в myMethod1 содержит вызов метода myMethod2, который генерирует ошибку. Блок CATCH в Method1 обрабатывает эту ошибку и отображает сообщение с информацией о сгенерированной ошибке Visual FoxPro.

Однако, если пример вызывает метод myMethod2 напрямую, например с помощью oMyObject.myMethod1() в oMyObject.myMethod2(), тогда предложению ON ERROR DO errorHandler нужно указать функциональную процедуру с именем errorHandler для обработки ошибки в myMethod2. После обработки ошибки, процедур ON ERROR возвращает управление программе с тем, чтобы могло быть исполнено предложение, следующее за предложением, вызвавшим ошибку.

 CopyCode imageСкопировать код
CLEAR
ON ERROR DO errorHandler && Создается функциональный обработчик ошибок для теста.
oMyObject=CREATEOBJECT("myClass")
oMyObject.myMethod1()
* oMyObject.myMethod2()  && Удалите символ комментария для тестирования этой строки кода.

DEFINE CLASS myClass AS Custom

   PROCEDURE myMethod1
      ? "myMethod1"
      TRY 
         ? "Вызов myMethod2 в блоке TRY метода myMethod1."
         THIS.myMethod2()
      CATCH TO omyError
         ? "Работает блок CATCH метода myMethod1. Захвачены: ", ;  
            omyError.ErrorNo, " ", omyError.Message
      ENDTRY
   ENDPROC

   PROCEDURE myMethod2
      ?
      ? "myMethod2"
      ? "Генерация ошибки в myMethod2."
      x=y         && Переменная  y не существует. Эту ошибку обрабатывает CATCH. 
      ? "Эта строка отображается, если CATCH не обработал предществующую ему ошибку."
   ENDPROC
ENDDEFINE

Смотрите также