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

ON ERROR-обработчик ошибок в Visual FoxPro

« Назад

Рассмотрим следующий код:

x = –5

a = Sqrt(x)

b = x * x

Поскольку в VFP параметр функции SQRT( ) не может быть меньше нуля, то при выполнении приведенного кода возникнет ошибка. При этом стандартный обработчик ошибок VFP прервет исполнение программы и выдаст показанное на рис. 7.1 сообщение.

122.1.-Обработка-ошибки-в-VFP

Рис. 7.1. Обработка ошибки в VFP

Стандартный обработчик ошибок можно заменить пользовательским.

Команда

ON ERROR [Command]

задает команду Command, выполняемую при возникновении ошибки VFP.

Как правило, Command – это вызов пользовательской программы или процедуры.

После выполнения Command работа программы возобновляется со строки, следующей за строкой, содержащей ошибку. Правда, если процедура-обработчик ошибки имеет команду RETRY, то строка с ошибкой будет выполнена еще раз.

При использовании ON ERROR без параметра Command восстанавливается стандартный обработчик ошибок VFP.

Процедура-обработчик ошибки не должна содержать команду ON ERROR. Если же такая команда в ней все же присутствует, то восстанавливается стандартный обработчик ошибок VFP.

Чтобы локализовать и описать возникшую ошибку, в ее обрабатывающую процедуру можно передать значения описанных в табл. 7.3 функций.

Таблица 7.3

Функции для локализации и расшифровки ошибки

Функция

Описание

ERROR( )

Возвращает номер последней ошибки; результат либо передается процедуре-обработчику ошибки, указанной в команде ON ERROR, либо функция вызывается в этой процедуре. Соответствующее сообщение об ошибке возвращает функция MESSAGE( )

MESSAGE([1])

Возвращает, если вызвана без параметра, строку, содержащую описание ошибки. При вызове с параметром функция вернет текст, имеющийся в строке программного кода, в которой возникла ошибка. Вызов с параметром нельзя использовать, если при компиляции (команда COMPILE) использована опция NODEBUG

LINENO([1])

Возвращает, если вызвана без параметра, номер строки с ошибкой относительно первой строки главной программы. При вызове с параметром функция вернет номер строки с ошибкой относительно первой строки текущего программного компонента.
Если работа программы приостановлена (команда SUSPEND), то LINENO( ) вернет номер выполняемой в этот момент строки; LINENO( ) вернет 0, если работа программы прервана (команда CANCEL)

PROGRAM([nLevel])

Возвращает, если параметр nLevel опущен, имя выполняемой программы. В случае ошибки возвращает имя программы, в которой произошла ошибка.
Чтобы отобразить иерархию вызова выполняемый программы, следует задать число отображаемых уровней (параметр nLevel). Это число не должно быть более 128.
Если nLevel равен 0 или 1, то PROGRAM( ) возвращает имя программы, находящейся на верхнем уровне иерархии. Если значение параметра nLevel превышает число уровней иерархии, функции вернет пустую строку.
Если для nLevel задать –1, то PROGRAM( ) вернет номер текущего уровня программы. PROGRAM(–1) вернет 0, если вызвана из командного окна

SYS(16 [, nLevel])

Аналогична функции PROGRAM( ), однако в отличие от последней возвращает вдобавок имя файла (с указанием пути), в котором расположена выполняемая процедура или функции. Имя файла не возвращается, если выполняемая программа является частью приложения.
Описание параметра nLevel дано при рассмотрении функции PROGRAM( )

SYS(2018)

Возвращает параметр, включаемый в строку сообщения об ошибке. Тип результата – символьный.
Употребляется для получения дополнительных сведений об ошибке. Например, если в выражении используется не существующая переменная, то в сообщение об ошибке включается дополнительный, возвращаемый SYS(2018) параметр, содержащий имя этой переменной

Пример 1. Иллюстрируется работа команды ON ERROR на коде, имеющем 2 ошибки.

&& Очищаем окно VFP

clear

&& ErrorHandler – имя процедуры, обрабатывающей ошибки

on error do ErrorHandler with Error( ), Message( ), Message(1), Lineno( ), Program( ), Sys(16)

x = –5

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

a = Sqrt(x)

&& Ошибка 2. Использование несуществующей переменной a

b = a * x

&& Восстанавливаем заданный по умолчанию обработчик ошибок

on error 

procedure ErrorHandler

parameters err, mes, mes1, lineNumber, progName, fileName

if Set('TEXTMERGE') = 'OFF'

    set textmerge on show

endif

&& Выводим дополнительно текст об ошибках в файл

set textmerge to d:\a.txt additive

\Номер ошибки: <<Transform(err)>>

\Описание ошибки: <<mes>>

\Локализация ошибки:

\оператор: <<Upper(mes1)>>

\номер строки: <<Transform(lineNumber)>>

\имя программы: <<progName>>

\имя файла: <<fileName>>

&& Закрываем файл, содержащий сообщения об ошибках

Fclose(_TEXT)

endProc

Сообщения, сгенерированные процедурой ErrorHandler:

Номер ошибки: 61

Описание ошибки: SQRT( ) argument cannot be negative

Локализация ошибки:

оператор: A = SQRT(X)

номер строки: 8

имя программы: TEST

имя файла: D:\ TEST.FXP

Номер ошибки: 12

Описание ошибки: Variable 'A' is not found

Локализация ошибки:

оператор: B = A * X

номер строки: 10

имя программы: TEST

имя файла: D:\ TEST.FXP

Пример 2. Печатаются значения элементов массива, сгенерированного функцией AERROR( ), при попытке добавить запись в таблицу Authors.dbf с недопустимым (отрицательным) значением поля AuthorId.

Встроим в таблицу Authors.dbf триггер вставки, содержащий указанное на рис. 7.2 выражение.

122.2.-Триггер-вставки-таблицы-Authors.dbf

Рис. 7.2. Триггер вставки таблицы Authors.dbf

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

clear

on error do ErrorHandler

close databases

open database 'd:\HomeLibrary\HomeLibrary'

&& Открываем таблицу Authors.dbf, активизируя индекс AuthorId

use Authors order tag AuthorId

m.AuthorId = –123

m.Author = 'Федоров Алексей Георгиевич'

m.InputDate = {^2005–01–01}

if not Seek(m.AuthorId)

insert into Authors from memvar

endif

on error 

procedure ErrorHandler

&& Направляем сообщения в окно VFP и в файл d:\a.txt

if Set('CONSOLE') = 'OFF'

    set console on

endif

set alternate to d:\a.txt additive

set alternate on

nRows = Aerror(aErrorArray)

for k = 1 to nRows

    ? 'Номер ошибки: ', aErrorArray(k, 1)

    ? 'Описание ошибки: ', aErrorArray(k, 2)

    if not IsNull(aErrorArray(k, 3)) then

  ? 'Параметр ошибки: ', aErrorArray(k, 3)

    endif

    if not IsNull(aErrorArray(k, 4)) then

    ? 'Номер рабочей области: ', aErrorArray(k, 4)

    Endif

    if not IsNull(aErrorArray(k, 5)) then

    do case

case aErrorArray(k, 5) = 1

? 'Ошибка при добавлении данных'

case aErrorArray(k, 5) = 2

? 'Ошибка при обновлении данных'

case aErrorArray(k, 5) = 3

? 'Ошибка при удалении данных'

    endCase

    endif

endFor

&& Закрываем файл, содержащий сообщения об ошибках

set alternate to

endProc

Сообщения, сгенерированные процедурой ErrorHandler:

Номер ошибки: 1539

Описание ошибки: Trigger failed

Номер рабочей области: 1

Ошибка при добавлении данных

После обнаружения ошибки для ее обработки употребляются в том числе приведенные в табл. 7.4 команды.

Таблица 7.4

Команды CANCEL, RESUME, RETRY, RETURN и SUSPEND

Команда

Описание

CANCEL

Прекращает исполнение текущей программы; все ее PRIVATE-переменные освобождаются

RESUME

Возобновляет исполнение приостановленной командой SUSPEND программы

RETRY

Повторно выполняет последнюю команду. Команда, в частности, полезна в процедурах, обрабатывающих ошибки, например, для повторного выполнения команды до тех пор, пока не выполнится успешно функция, блокирующая запись или таблицу. Управление процессом осуществляется командой SET REPROCESS, задающей число попыток или время, в течение которого блокировки ожидается снятие блокировки

RETURN [eExpression
               
| TO MASTER

                | TO ProcedureName]

Передает управление вызывающей программе, возвращая значение eExpression. Управление передается вызывающей программе верхнего уровня, если задана опции TO MASTER, или процедуре ProcedureName, если задана последняя опция команды.
Если команда RETURN опущена или употреблена без eExpression, то функция вернет .T.
RETURN освобождает все PRIVATE-переменные прерванной программы

SUSPEND

Приостанавливает выполнение текущей программы. После выполнения SUSPEND имеется возможность выполнить необходимые для прояснения ситуации действия: проверить значения переменных, открыть окно трассировки или отладки и т. д. Работа приостановленной программы возобновляется командой RESUME

При необходимости сведения об ошибке можно очистить.

Команда

CLEAR ERROR

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

AERROR( ) – будет возвращать 0;

ERROR( ) – будет возвращать 0;

MESSAGE( ), MESSAGE(1) и SYS(2018) – будут возвращать чистую строку.

Команду CLEAR ERROR нельзя употреблять внутри конструкции TRY ... CATCH ... FINALLY: объект-исключение после употребления CLEAR ERROR внутри конструкции может стать недоступным.