Axiom Справочник языка

13 · Обработка ошибок

Обработка ошибок

Отказ во время выполнения — недоступный файл, недопустимый аргумент, деление на ноль — не всегда означает конец работы. Часто нужно освободить ресурс, записать сведения о случившемся и продолжить с другого шага. Для этого в языке есть три средства: оператор TRY с блоками CATCH и FINALLY, оператор ERROR, создающий отказ по прикладному условию, и встроенный тип ERROR, из которого читаются код, сообщение и место отказа.

Защищённый участок и его блоки

Оператор TRY размечает участок, отказ внутри которого программа готова обработать сама. Инструкции этого участка выполняются обычным порядком; если одна из них завершается ошибкой, остаток участка пропускается, а управление переходит в CATCH, где доступны сведения о случившемся. Блок FINALLY выполняет завершающие действия с ресурсом и срабатывает как при обычном выходе, так и при передаче ошибки дальше. Достаточно одного из двух блоков.

Речь идёт об ошибках уже запущенной программы. Ошибки лексического, синтаксического и семантического анализа обнаруживаются до запуска, поэтому TRY их не перехватывает.

Программа ниже делит на ноль внутри защищённого участка:

TRY
    PRINT 10 \ 0
CATCH err
    PRINT err.Code
FINALLY
    PRINT "finally"
END TRY
PRINT "after"

Ожидаемый вывод:

MB3001
finally
after

Строка с делением выполнилась один раз и после обработки не повторялась, поэтому вместо числа напечатан код MB3001. Затем сработал FINALLY со своим сообщением, и только после него управление продолжилось за END TRY — так появилась третья строка after. Порядок вывода повторяет порядок работы: обработка, завершение, продолжение.

Сведения об ошибке

Строка CATCH err объявляет переменную err встроенного типа ERROR: отдельный DIM или CONST не нужен, потому что имя введено самим обработчиком. Значение переменная получает при переходе в CATCH, внутри блока доступна только для чтения, но константой CONST при этом не является. Правила объявления и области видимости собраны в статье TRY.

Тип ERROR содержит четыре поля, заранее определённых языком, поэтому объявлять их в программе не требуется. В записи err.Code имя переменной — err, точка обозначает обращение к полю, а Code — имя поля; вся запись читает значение поля. Все четыре поля доступны только для чтения. Их типы и назначение:

ПолеТипНазначение
CodeSTRINGКод системной или пользовательской ошибки.
MessageSTRINGАнглийский текст системной ошибки либо исходный текст пользовательского сообщения ERROR.
LineINTEGERНомер строки исходника начиная с 1; 0, если место неизвестно.
ColumnINTEGERНомер столбца исходника начиная с 1; 0, если место неизвестно.

Язык сообщений

Поле Message хранит системный текст на английском языке независимо от языка интерфейса IDE. Текст, переданный оператору ERROR явно, сохраняется без перевода. Различие между системным и прикладным сообщением разобрано в статье TRY.

Пользовательские ошибки

Когда отказ означает нарушение прикладного условия, программа создаёт его сама: ERROR с кодом и необязательным сообщением вводит новую ошибку, а ERROR со значением ошибки передаёт уже полученный отказ наружу, сохраняя исходное место. Оба случая обрабатываются тем же TRY, что и системные ошибки, а после успешной обработки программа продолжается за END TRY.

Справочные статьи

TRY, CATCH, FINALLY · ERROR · Возврат через FINALLY · Файловые отказы · Диагностика массивов