ОБРАБОТКА ОШИБОК 

В процессе выполнения программного кода ABL возможно возникновение ряда системных ошибок. При возникновении системной ошибки AVM осуществляет вывод соответствующего сообщения о возникшей ошибке. Выводимые сообщения представляют собой краткое описание ошибки и ее цифровой код, указываемый в скобках. По цифровому коду ошибки возможно найти ее подробное описание и способы устранения в базе знаний.

Выводимые описания ошибок хранятся в файле promsgs и могут быть локализованы.

Для фиксации всех возникающих в приложении системных ошибок, в OpenEdge ABL(4GL) существует системная переменная ERROR-STATUS типа HANDLE. Данная переменная обладает двумя атрибутами:

  • ERROR - тип LOGICAL, показывающее наличие (значение TRUE) или отсутствие (значение FALSE) ошибок;
  • NUM-MESSAGES - тип INTEGER, хранящее количество возникших сообщений об ошибке.

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

  • ERROR-STATUS:GET-MESSAGE(N) - описание N-ой ошибки (типа CHAR);
  • ERROR-STATUS:GET-NUMBER(N) - цифровой код N-ой ошибки (тип INTEGER).

Ряд операторов ABL, могут применяться с опцией NO-ERROR. Данная опция предотвращает реакцию AVM на возникающие в них ошибки, вывод их на экран и прерывание выполнения программного кода. При этом сами ошибки все же фиксируются в системной переменной ERROR-STATUS.

Вывести все возникшие при выполнении процедуры ошибки можно следующим образом:

IF ERROR-STATUS:ERROR = True THEN  
DO i = 1 TO ERROR-STATUS:NUM-MESSAGES:
   DISPLAY "Возникла ошибка с кодом:" ERROR-STATUS:GET-NUMBER(i)
"Сообщение:" ERROR-STATUS:GET-MESSAGE(i).
END.

ELSE
DISPLAY "Ошибок нет".

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

DEF VAR iDate AS DATE NO-UNDO.
FIND FIRST loan WHERE loan.cust-id EQ 0 NO-ERROR.
iDate = loan.open-date.

Если искомая запись в таблице loan не будет найдена, то это не вызовет прерывание по ошибке поиска, так как FIND используется с опцией NO-ERROR. Но при этом в дальнейшем возникнет ошибка в операторе присваивания.

Избежать данной ошибки можно предварительной проверкой того, что искомая запись была найдена. Сделать это можно с помощью оператора AVAILABLE:

DEF VAR iDate AS DATE NO-UNDO.
FIND FIRST loan WHERE loan.cust-id EQ 0 NO-ERROR.
IF AVAIL loan THEN iDate = loan.open-date.


БЛОК CATCH


С развитием OpenEdge ABL появилась структурированная модель представления ошибок. Данная модель представляет все возникающие ошибки объектами класса, а так же позволяет разработчику определять собственные классы ошибок.

Блок CATCH всегда располагается внутри внешнего ассоциированного блока и обрабатывает происходящие в нем ошибки. CATCH подавляет системные сообщения во внешнем блоке (не обязательно использовать NO-ERROR).

associate-block-statements

CATCH error-variable AS [CLASS] error-class:
      catch-logic
END [CATCH].

[associate-block-end]

associate-block-statements - тело внешнего (ассоциированного) блока.

Блок CATCH может использоваться внутри следующих блоков:

  • CATCH block (рекурсивно, блок CATCH внутри блока CATCH);
  • DO (в конструкции DO TRANSACTION или DO ON ERROR, UNDO);
  • FOR;
  • REPEAT;
  • В конце файла процедуры (.p procedure file);
  • Внутри процедуры;
  • Внутри функции определенной пользователем;
  • Внутри методов, свойств, конструкторов и деструкторов;
  • ON;
  • FINALLY.

error-variable - переменная объект - экземпляр класса error-class. Явное описание переменной не требуется.

error-class - один из встроенных классов ошибок:

  • Progress.Lang.ProError - родительский класс для всех классов ошибок;
  • Progress.Lang.SysError - класс системных ошибок;
  • Progress.Lang.AppError - класс ошибок приложения;
  • Progress.Lang.Error - интерфейс определяющий основные методы для классов ошибок.

Интерфейс Progress.Lang.Error определяет следующие методы и свойства:

  • CallStack - свойство, хранит строку стека вызовов в момент возникновения ошибки. (работает если SESSION:ERROR-STACK-TRACE = TRUE или стартовый параметр -errorstack);
  • NumMessages - свойство, хранит количество сообщений;
  • Severity - свойтво для реализации ранжирования сообщений по степени серьезности;
  • GetMessage(index) - метод, возвращает текст сообщения ошибки с номером index;
  • GetMessageNum(index) - метод, возвращает код сообщения ошибки с номером index;.

Класс Progress.Lang.ProError является супер классом для всех классов ошибок ABL и реализует интерфейс Progress.Lang.Error..

Класс Progress.Lang.SysError является классом системных ошибок возникающих при выполнении операторов ABL. Вы НЕ можете наследовать свои классы ошибок от данного класса.

Класс Progress.Lang.AppError является родительским классом для всех ошибок приложения. Все собственные пользовательские классы ошибок приложения должны быть подклассами данного класса.

Блок CATCH располагается в конце ассоциированного с ним блока и выполняется только в случае возникновения соответствующего класса ошибки в ассоциированном блоке.

DEF VAR iDate AS DATE NO-UNDO.
FIND FIRST loan WHERE loan.cust-id EQ 0.
iDate = loan.open-date.

CATCH eErr AS Progress.Lang.Error:
MESSAGE eErr:GetMessageNum(1) + " " + eErr:GetMessage(1)
VIEW-AS ALERT-BOX BUTTONS OK.
END CATCH.

В данном примере блок CATCH располагается в конце процедурного блока.

После блока CATCH можно использовать блок FINALLY, который также может содержать в себе блок CATCH.


БЛОК FINALLY


Вызов FINALLY блока осуществляется в конце каждой итерации ассоциированного блока независимо от того возникла ли какая-либо ошибка в ассоциированном блоке или нет.

Блок FINALLY должен всегда идти после всех блоков CATCH, если таковые имеются в ассоциированном блоке.

associate-block-statements

FINALLY:
      finally-logic
END [FINALLY].

associate-block-end

Блок FINALLY может использоваться внутри одного из следующих блоков:

  • DO
  • FOR
  • REPEAT

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

Вы здесь: Главная Основы ABL ОБРАБОТКА ОШИБОК