Этот сайт посвящается администрированию баз данных OpenEdge Progress.
Не корысти ради, а познания для!

С уважением,
Валерий Башкатов
Сайт разработан при участии компании Progress Technologies, официального дистрибьютора Progress Software Corp. на территории стран СНГ и Латвии.

RSS RSS подписка на обновления сайта

Поиск по сайту

Лучшие материалы

Orphus System
На сайте функционирует система коррекции ошибок. Обнаружив неточность в тексте, выделите её и нажмите Ctrl+Enter



Результаты опроса: Нужны ли книги по Progress OpenEdge на русском языке? (опрос проводился с мая 2009 по ноябрь 2010)

Да, нужны. Потому что будет легче понять материал - 268
Нет, не нужны. Достаточно материалов на английском языке - 10
Не знаю, мне всё равно - 6

А знаете ли вы что..



Введение в условную обработку




Condition handling (условная обработка), error handling (обработка ошибок), и exception handling (обработка исключений) - это термины программирования, означающие выполнение определенных действий при возникновении некоторых событий, которые прерывают нормальную работу приложения. В зависимости от языка, используются названия conditions (условия), errors (ошибки) или exceptions (исключения). В ABL, condition имеет отношение ко всем возможным прерываниям. Error это наиболее общий тип condition. Error возникает тогда, когда AVM (ABL Virtual Machine) больше не в состоянии продолжать нормальное выполнение ABL кода. Ошибки, возникающие при работе AVM, называются system errors (системные ошибки). Ошибки, связанные с программированием, называются application errors (ошибки приложения). В некоторых языках, ошибки, которые нельзя исправить, называются unrecoverable errors (не исправимые ошибки). В ABL они представлены состоянием STOP. Вообще condition отличается от других возникающих событий, поскольку оно неожидаемое и требует определенного действия для восстановления работы приложения. В ABL, condition всегда определяет действие по умолчанию, которое называется default error handling (обработчик ошибок по умолчанию). Это защищает постоянные данные, а также обеспечивает выбор метода для восстановления рабочего потока (потока приложения). Вы можете создавать свои ABL приложения, используя default error handling, подавлять его или заменять на собственный обработчик ошибок. Чтобы быть точным, тема этого документа, это condition handling. Поскольку condition handling в ABL связан с ошибками (ERROR), то error handling является синонимом condition handling, который довольно часто используется в качестве термина в документации OpenEdge.

ABL имеет четыре типа событий, которые представлены следующими ключевыми словами: ERROR, ENDKEY, STOP и QUIT.

Событие ERROR представляет большинство run-time ошибок в OpenEdge. Оно возникает в следующих случаях:

 

  • Когда AVM не в состоянии выполнить ABL код, обычно на уровне операторов. Например, когда оператор FIND не находит соответствующей записи, то возникает ошибка. Такие сбои, обнаруженные AVM, вызывают событие ERROR. Эти ошибки известны под именем системные ошибки. Такие ошибки идентифицируется числовым номером и описательным сообщением.
  • Когда Ваше приложение запускает оператор RETURN ERROR. Ошибки, сгенерированные таким образом называются программными ошибками (application error).
  • Когда пользователь приложения наживает клавишу, связанную с кодом (keycode) ERROR. Этот тип ошибки в современном программировании был заменен UI триггерами.

 

Событие ENDKEY возникает во время выполнения в случаях, которые имели значения для более старого стиля программирования, который тесно связан между UI (user interfaces) и обработкой записей в базе данных. Поскольку обычно приложение не должно смешивать ввод данных с транзакционными блоками в одной и той же процедуре, то событие ENDKEY практически не используется в современных приложениях. Событие ENDKEY возникает когда:

 

  • при вводе данных, пользователь нажимает клавишу, связанную с кодом (keycode) ENDKEY.
  • приложение достигло окончания входного потока.

 

К событию ENDKEY имеет отношение и другой код (keycode) который называется END-ERROR, который определяет большинство событий имеющих отношение к старому стилю программирования и обеспечивает их обработку по умолчанию.

Событие STOP, возникает во время выполнения некоторого условия, которое требует, чтобы приложение завершило работу сессии. Стандартная обработка события STOP включает выполнение отката всех текущих транзакций. Событие возникает в следующих случаях:

 

  • приложение выполнило оператор STOP.
  • пользователь приложения нажал клавишу, связанную с кодом STOP
  • AVM столкнулся с системной ошибкой, которую он посчитал не исправимой. Например, если AVM обнаружил потерю связи с базой данных, или не смог найти процедуру или программу, запущенную оператором RUN, то в таких случаях AVM сгенерирует событие STOP.

 

Событие QUIT возникает только тогда, когда ваше приложение выполнит оператор QUIT.

Традиционная обработка ошибок

В этой части, я вкратце расскажу о концепции и механизме традиционной обработки ошибок. Более подробно об этом будет рассказано в отдельной одноименной главе.

Стандартный обработчик ошибок (или еще обработка ошибок по умолчанию) определяется на блочном уровне и считается собственностью блока. Но это утверждение может меняться в зависимости от типа блока, и от того, является ли блок частью транзакции. Рассмотрим следующую небольшую программу:

FIND FIRST Customer WHERE CustNum = 1000.
DISPLAY Customer.Name.

Поскольку база Sports2000 не содержит записи в таблице Customer с таким параметром (CustNum = 1000), то работа оператора FIND завершится с ошибкой. Когда это произойдет, AVM выполнит следующие действия:

 

  • остановит выполнение блока с ошибочным оператором;
  • отобразит на экран сообщение, описывающее возникшую ошибку, в данном случае, это будет выглядеть так:  
  • проверит блок, который содержит ошибочный оператор, чтобы получить команды обработки ошибок, заданные по умолчанию;
  • обработка ошибок всегда начинается с выполнения UNDO. AVM откатит все изменения в переменных и во временных таблицах, у которых не была установлена опция NO-UNDO. Так же, AVM отменит текущую транзакцию, если таковая существует. Транзакция может возникнуть в блоке если:
    • изменено поле в базе данных;
    • блок имеет в своем определении ключевое слово TRANSACTION;
    • если этот блок находится в другом блоке, который в свою очередь входит в транзакцию.
В нашей программе нет транзакции, поэтому отменять ни чего не нужно. Более подробно работа транзакционного механизма описана в документации OpenEdge Development: ABL Handbook;
  • AVM пытается выбрать один способов перехода по умолчанию. В зависимости от контекста, это может быть RETRY, LEAVE или NEXT. В нашем случае это будет LEAVE;
  • AVM прервет работу программы и вернется в операционную систему или среду OpenEdge, из которой программа была запущена.

 

Фраза ON ERROR позволяет изменить обработку ошибок для таких блоков как DO, FOR или REPEAT. Например:

DO ON ERROR UNDO, RETURN:
FIND FIRST Customer WHERE CustNum = 1000.
END.

Если этот код был включен во внутреннюю процедуру или другую вызываемую подпрограмму, то сбой оператора FIND приведет AVM к фразе ON ERROR и к опции RETURN. RETURN вынудит текущую программу завершиться и вернуться в вызывающую программу.

Некоторые ABL операторы поддерживают опцию NO-ERROR. Эта опция указывает AVM о необходимости перенаправления обработки ошибки по другому пути. Например, следующая программа не завершится с ошибкой и закончит свою работу нормально:

FIND FIRST Customer WHERE CustNum = 1000 NO-ERROR.
IF ERROR-STATUS:ERROR = TRUE THEN
MESSAGE ERROR-STATUS:GET-MESSAGE(1).

Информация относительно возникшей ошибки в операторе с опцией NO-ERROR передается в system handle ERROR-STATUS.

Игнорирование ошибки с помощью NO-ERROR может быть использовано вами в следующих случаях:

 

  • Когда необходимо отменить обработку ошибки по умолчанию;
  • Когда необходимо запретить видеть пользователю стандартное сообщение об ошибке;
  • Когда необходимо обеспечить собственную обработку ошибки;
  • Когда необходимо с помощью ERROR-STATUS определить, возникает ли конкретная ошибка.

 

В следующем примере происходит перехват стандартного сообщение об ошибке и вывод на экран собственного сообщения.

FIND FIRST Customer WHERE CustNum = 1000 NO-ERROR.
IF ERROR-STATUS:ERROR=TRUE THEN
MESSAGE "Произошла ошибка!" view-as alert-box.

Вы можете самостоятельно задать сообщение об ошибке с помощью оператора RETURN ERROR и обработать его. При этом стандартная обработка ошибки может быть выполнена в вызывающей программе. Вы можете обратиться к вашему сообщению с помощью функции RETURN-VALUE. В следующем примере, код подавляет стандартный обработчик ошибок как во внутренней, так и во внешней процедурах. По существу здесь происходит замена стандартного сообщение ошибки на собственное, которое возвращается вызывающему оператору и отображается на экран после оператора RUN.

PROCEDURE Customer1000:
FIND FIRST Customer WHERE CustNum = 1000 NO-ERROR.
IF ERROR-STATUS:ERROR = TRUE THEN
RETURN ERROR "Пользователя с кодом 1000 нет в базе данных.".
END PROCEDURE.
RUN Customer1000 NO-ERROR.
IF ERROR-STATUS:ERROR = TRUE THEN
DISPLAY RETURN-VALUE FORMAT "x(60)".
ELSE
DISPLAY "Работа программы завершена успешно!" FORMAT "x(60)".

Все выше приведенные примеры легко демонстрируют традиционный способ обработки ошибок.

Структурная обработка ошибок

Структурная обработка ошибок (structured error handling) это модель, которая имеется во многих языках, но обычно она ассоциируется с объектно-ориентированными языками. Она характеризуется следующими признаками:

 

  • Представление всех ошибок в качестве объектов (образцы класса);
  • Позволяет определять ваши собственные типы ошибок (классы);
  • Позволяет явно создавать ошибку;
  • Позволяет захватывать конкретную ошибку в специфическом контексте (ABL блок);
  • Позволяет распространять (re-throw) ошибки из текущего контекста (внутренний блок) на непосредственный внешний контекст (внешний блок). Другими словами, когда ошибка возникает в текущем контексте, вы можете перенаправить ее в вызывающий контекст, для осуществления обработки;
  • Позволяет определять код, который выполняется при завершении некоторого связанного кода, чтобы проверять действительно ли связанный код выполнился успешно (блок FINALLY).

 

Структурная обработка ошибок имеет несколько синтаксических разновидностей, но вы можете узнать его по одному общему синтаксису: try и catch. Вот пример такого псевдо кода:

TRY /* to execute this code */
{
WRITE FILE myAddresses.
}
CATCH errorFileLocked /* and if the errorFileLocked error is thrown (raised), let the error handling behavior here catch (handle) the error instead of the system’s default behavior. */
{
SEND MESSAGE “File currently unavailable.”
}
CATCH errorNoWritePermission /* or if the errorNoWritePermission error is thrown, use this behavior.*/
{
SEND MESSAGE “You do not have permission to write files.”
}

Конструкция try обеспечивает способ определения блока, с которым вы можете связать обработчик ошибок. Catch позволяет вам определять обработчик ошибки и связывать его с ошибкой. Когда система обнаруживает ошибку в try блоке, то она запускает код в catch блоке, связанном с этой ошибкой. Если в catch блоке не будет обнаружено соответствующего обработчика, то в этом случае всё зависит от конкретного языка, но в большинстве случаев, call stack будет оставаться открыт, пока система не найдет подходящий catch блок.

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

Поскольку ABL это блок-структурный язык, то он не нуждается в наличии конструкции подобной try. ABL блоки это нечто большее чем обычный try блок. Поскольку ABL язык ориентирован на базы данных, все его блоки для защиты данных, носят отменяемый характер, т.е. позволяют выполнять откат изменений в случае сбоя. Это означает, что у вас есть большое количество различных опций для успешного возобновления работы после ошибки. Все блоки имеют неявный обработчик ошибок некоторого типа, за исключением обычного блока DO (DO …END, без указания опции TRANSACTION или без опций обработчика ошибок). Явная обработка ошибок обеспечивается фразой ON ERROR и её множеством опций. Стандартный обработчик ошибок обеспечивается не явным указанием фразы ON ERROR. Короче говоря, явные и неявные указания ON ERROR составляют традиционный обработчик ошибок. Чтобы представить ошибки как объекты, ABL добавляет встроенные классы и оператор CATCH. Эти изменения обеспечивают основу механизма структурной обработки ошибок в ABL. Вот простой пример:

DO ON ERROR UNDO, RETURN:
FIND FIRST Customer WHERE CustNum = 1000.
CATCH eSystemError AS Progress.Lang.SysError:
MESSAGE "Not a valid customer number.".
UNDO, THROW eSystemError.
END CATCH.
END. /* DO */

Явное указание ON ERROR определяет обработчик ошибок для блока. В традиционном обработчике ошибок, если в пределах блока возникнет любая ошибка, то выполняется опция RETURN. А в структурном обработчике, RETURN будет выполнен только, если ошибка не обрабатывается блоком CATCH. Как только в операторе FIND возникает сбой, он генерирует системную ошибку и выполняется CATCH блок. Этот блок завершается с опцией UNDO, оператор THROW направляет обработку объекта eSystemError в блок DO.

Напомню, что эта часть была просто быстрым введением в понятия структурного обработчика ошибок, и каким образом эти понятия реализованы в ABL. Более подробно об этой модели будет рассказано в главе «Использование структурного обработчика ошибок».






Главная |  Статьи |  Книги |  Гостевая |  Ссылки |  От автора |  Download ProKb


������ ᠩ� pr Online ProKB Blogger Welcome to Russian Progress Users Group at Facebook Welcome to Russian Progress Users Group at LinkedIn
© 2009 - 2011 Все права на материалы, находящиеся на сайте www.openedge.ru, охраняются в соответствии с законодательством РФ, в том числе, об авторском праве и смежных правах.
При любом использовании материалов сайта ссылка на источник обязательна.