Приложение 2 - Ошибки
Руководство пользователя REBOL/Core Основное содержание Отправьте нам отзыв
Содержание:
1. Обзор
2. Категории ошибок
2.1 Синтаксические ошибки
2.2 Ошибки сценария
2.3 Математические ошибки
2.4 Ошибки доступа
2.5 Ошибки пользователя
2.6 Внутренние ошибки
3. Перехват ошибок
4. Объект ошибки
5. Генерация ошибок
6. Сообщения об ошибках
6.1 Синтаксические ошибки
6.2 Ошибки сценария
6.3 Ошибки доступа
6.4 Внутренние ошибки
1. Обзор
Ошибки - это исключения, которые возникают при возникновении определенных нестандартных условий. Эти условия варьируются от синтаксических ошибок до ошибок доступа к файлам или сети. Вот несколько примеров:
12-30
** Syntax Error: Invalid date -- 12-30.
** Where: (line 1) 12-30
1 / 0
** Math Error: Attempt to divide by zero.
** Where: 1 / 0
read %nofile.r
** Access Error: Cannot open /example/nofile.r.
** Where: read %nofile.r
Ошибки обрабатываются внутри системы как значения типов данных error!. Ошибка - это объект, который при оценке выводит сообщение об ошибке и останавливается. Вы также можете обнаруживать ошибки и обрабатывать их в своем скрипте. Ошибки можно передавать в функции, возвращать из функций и присваивать переменным.
2. Категории ошибок
Есть несколько категорий ошибок.
2.1 Ошибки синтаксиса
Синтаксические ошибки возникают, когда сценарий неправильно использует синтаксис REBOL. Например, если закрывающая скобка отсутствует или в строке отсутствует закрывающая кавычка, произойдет синтаксическая ошибка. Эти ошибки возникают только во время загрузки или оценки файла или строки.
2.2 Ошибки скрипта
Ошибки сценария - это общие ошибки времени выполнения. Например, неверный аргумент функции вызовет ошибку сценария.
2.3 Математические ошибки
Математические ошибки возникают, когда математическая операция не может быть обработана. Например, при попытке разделить на ноль возникнет ошибка.
2.4 Ошибки доступа
Ошибки доступа возникают, когда возникает проблема с доступом к файлу, порту или сети. Например, ошибка доступа произойдет при попытке прочитать несуществующий файл.
2.5 Ошибки пользователей
Пользовательские ошибки генерируются явным образом сценарием, создавая значение ошибки и возвращая его.
2.6 Внутренние ошибки
Внутри интерпретатора REBOL возникают внутренние ошибки.
3. Выявление ошибок
Вы можете отловить ошибки с помощью функции try. Функция try аналогична функции do. Он оценивает блок, но всегда возвращает значение, даже если возникает ошибка.
Если ошибки не возникает, try возвращает значение блока. Например:
print try [100 / 10]
10
При возникновении ошибки попытка возвращает ошибку. Если вы напишете:
print try [100 / 0]
** Math Error: Attempt to divide by zero.
** Where: 100 / 0
ошибка возвращается при try, и функция печати print не может ее обработать.
Чтобы обрабатывать ошибки в сценарии, вы должны предотвратить оценку ошибки REBOL. Вы можете предотвратить оценку ошибки, передав её функции. Например, функция error? вернет истину при возниктовении ошибки:
print error? try [100 / 0]
true
YВы также можете распечатать тип данных значения, возвращенного при попытке:
print type? try [100 / 0]
error!
Функция disarm (снятия с охраны) преобразует ошибку в объект ошибки, который можно исследовать. В приведенном ниже примере переменная ошибки содержит объект ошибки:
error: disarm try [100 / 0]
Когда ошибка снята с охраны, это будет тип данных object!, а не тип данных error!. Оценка снятого с охраны объекта не вызовет ошибки:
probe disarm try [100 / 0]
make object! [
code: 400
type: 'math
id: 'zero-divide
arg1: none
arg2: none
arg3: none
near: [100 / 0]
where: none
]
Значения ошибок могут быть установлены в слово перед снятием с охраны. Чтобы присвоить слову ошибку, ему должна предшествовать функция, предотвращающая дальнейшее распространение ошибки. Например:
disarm err: try [100 / 0]
Установка переменной позволяет вам получить доступ к значению блока позже. В приведенном ниже примере будет напечатано значение ошибки или не ошибка:
either error? result: try [100 / 0] [
probe disarm result
][
print result
]
4. Объект ошибки
Показанный выше объект ошибки имеет структуру:
make object! [
code: 400
type: 'math
id: 'zero-divide
arg1: none
arg2: none
arg3: none
near: [100 / 0]
where: none
]
Где находятся поля:
| | code | Номер кода ошибки. Они устарели и не должны использоваться.
|
| | type | Поле типа определяет категорию ошибки. Это всегда словесный тип данных syntax (синтаксис), script (сценарий), math (математика), access (доступ), user (пользователь) и internal (внутренний).
|
| | id | Поле id - это название ошибки в виде слова. Он определяет конкретную ошибку, которая произошла в категории ошибок.
|
| | arg1 | Это поле содержит первый аргумент сообщения об ошибке. Например, он может включать тип данных значения, вызвавшего ошибку.
|
| | arg2 | Это поле содержит второй аргумент сообщения об ошибке.
|
| | arg3 | Это поле содержит третий аргумент сообщения об ошибке.
|
| | near | Ближнее поле - это фрагмент кода, который показывает, где произошла ошибка.
|
| | where | Поле where зарезервировано.
|
Вы можете написать код, который проверяет любое из полей объекта ошибки. В этом примере ошибка выводится только тогда, когда идентификатор ошибки указывает на ошибку деления на ноль:
error: disarm try [1 / 0]
if error/id = 'zero-divide [
print {It is a Divide by Zero error}
]
It is a Divide by Zero error
Слово идентификатора ошибки также предоставляет блок ошибки, который будет напечатан интерпретатором. Например:
error: disarm try [print zap]
probe get error/id
[:arg1 "has no value"]
Этот блок определяется объектом система/ошибки.
5. Создание ошибок
Могут возникнуть ошибки пользователя. Самый простой способ сгенерировать ошибку - это make. Вот пример:
make error! "this is an error"
** User Error: this is an error.
** Where: make error! "this is an error"
Любая из существующих ошибок может быть сгенерирована путем внесения ошибки с помощью аргумента блока. Этот блок содержит имя категории ошибки и имя идентификатора сообщения об ошибке. Если для ошибки требуются аргументы, аргументы следуют за именем идентификатора сообщения. Аргументы определяют значения arg1, arg2 и arg3 в объекте ошибки. Вот пример:
make error! [script expect-set series! number!]
** Script Error: Expected one of: series! - not: number!.
** Where: make error! [script expect-set series! number!]
Пользовательские ошибки могут быть внесены в категорию user объекта system/error (система/ошибка). Это делается путем создания новой категории пользователей с новыми записями. Эти записи используются при создании ошибок. Например, следующий пример вводит ошибку в категорию пользователя:
system/error/user: make system/error/user [
my-error: "a simple error"
]
Теперь ошибка может быть сгенерирована с использованием идентификатора сообщения my-error:
if error? err: try [
make error! [user my-error]
] [probe disarm err]
make object! [
code: 803
type: 'user
id: 'my-error
arg1: none
arg2: none
arg3: none
near: [make error! [user my-error]]
where: none
]
Чтобы создать более информативные ошибки, определите ошибку, которая использует данные, доступные при ее создании. Эти данные включаются в снятый с охраны объект ошибки и печатаются как часть сообщения об ошибке. Например, чтобы использовать все три пробела аргументов в объекте ошибки:
system/error/user: make system/error/user [
my-error: [:arg1 "doesn't go into" :arg2 "using" :arg3]
]
if error? err: try [
make error! [user my-error [this] "that" my-function]
] [probe disarm err]
make object! [
code: 803
type: 'user
id: 'my-error
arg1: [this]
arg2: "that"
arg3: 'my-function
near: [make error! [user my-error [this] "that" my-function]]
where: none
]
Сообщение об ошибке, созданное для my-error, можно распечатать, не останавливая скрипт:
disarmed: disarm err
print bind (get disarmed/id) (in disarmed 'id)
this doesn't go into that using my-function
Новая категория библиотеки может быть создана, если есть необходимость сгруппировать серию ошибок вместе, создав новую категорию в system/error::
system/error: make system/error [
my-errors: make object! [
code: 1000
type: "My Error Category"
error1: "a simple error"
error2: [:arg1 "doesn't go into" :arg2 "using" :arg3]
]
]
Тип определен в объекте ошибки будет напечатан типом ошибки , когда генерируются ошибка. В следующем примере показано создание ошибки как из error1, так и из error2 в категории my-error.
Генерация ошибки из error1. Эта ошибка не требует аргументов:
disarmed: disarm try [make error! [my-errors error1]]
print get disarmed/id
a simple error
Для генерации ошибки из error2 требуются три аргумента:
disarmed: disarm try [
make error! [my-errors error2 [this] "that" my-function]]
print bind (get disarmed/id) (in disarmed 'id)
this doesn't go into that using my-function
Наконец, описание, которое возвращает ошибки, определенные в my-error, можно получить с помощью:
probe get in get disarmed/type 'type
My Error Category
6. Сообщения об ошибках
Ниже приведен список всех ошибок, определенных в каталоге ошибок объекта system/error.
6.1 Синтаксические ошибки
6.1.1 недействительно
Данные не могут быть преобразованы в допустимый тип данных REBOL. Другими словами, было оценено искаженное значение.
Сообщение:
["Invalid" :arg1 "--" :arg2]
Пример:
filter-error try [load "1024AD"]
** Syntax Error: Invalid integer -- 1024AD
** Where: (line 1) 1024AD
6.1.2 отсутствует
Блок, строка или выражение-скобка остались незакрытыми.
Сообщение:
["Missing" :arg2 "at" :arg1]
Пример:
filter-error try [load "("]
** Syntax Error: Missing ) at end-of-script
** Where: (line 1) (
6.1.3 заголовок
Была сделана попытка оценить файл как сценарий REBOL, но файл не имел заголовка REBOL.
Сообщение:
Script is missing a REBOL header
Пример:
write %no-header.r {print "data"}
filter-error try [do %no-header.r]
** Syntax Error: Script is missing a REBOL header
** Where: do %no-header.r
6.2 Ошибки скрипта
6.2.1 без значения
Была сделана попытка оценить неопределенное слово.
Сообщение:
[:arg1 "has no value"]
Пример:
filter-error try [undefined-word]
** Script Error: undefined-word has no value
** Where: undefined-word
6.2.2 need-value (потребность)
Была сделана попытка определить слово ни к чему. Установочное слово использовалось без аргументов.
Сообщение:
[:arg1 "needs a value"]
Пример:
filter-error try [set-to-nothing:]
** Script Error: set-to-nothing needs a value
** Where: set-to-nothing:
6.2.3 no-arg
Функция была оценена без предоставления всех ожидаемых аргументов.
Сообщение:
[:arg1 "is missing its" :arg2 "argument"]
Example:
f: func [b][probe b]
filter-error try [f]
** Script Error: f is missing its b argument
** Where: f
6.2.4 expect-arg< (ожидаемый аргумент)/h4>
Функция предоставила аргумент типа данных, которого она не ожидала.
Сообщение:
[:arg1 "expected" :arg2 "argument of type:" :arg3]
Пример:
f: func [b [block!]][probe b]
filter-error try [f "string"]
** Script Error: f expected b argument of type: block
** Where: f "string"
6.2.5 expect-set (ожидаемый набор)
Два ряда значений использовались вместе несовместимым образом. Например, при попытке объединения (union) строки и блока.
Сообщение:
["Expected one of:" :arg1 "- not:" :arg2]
Пример:
filter-error try [union [a b c] "a b c"]
** Script Error: Expected one of: block! - not: string!
** Where: union [a b c] "a b c"
6.2.6 invalid-arg (неверный аргумент)
Это общая ошибка обработки значений, которые использовались неправильно. Например, когда заданное слово используется внутри блока спецификации функции.
Сообщение:
["Invalid argument:" :arg1]
Пример:
filter-error try [f: func [word:][probe word]]
** Script Error: Invalid argument: word
** Where: func [word:] [probe word]
6.2.7 invalid-op (недействительный)
Была сделана попытка использовать переопределенный оператор. Используемый оператор больше не является допустимым оператором.
Сообщение:
["Invalid operator:" :arg1]
Пример:
*: "operator redefined to a string"
filter-error try [5 * 10]
** Script Error: Invalid operator: *
** Where: 5 * 10
6.2.8 no-op-arg
Был использован математический оператор или оператор сравнения без предоставления второго аргумента.
Сообщение:
Operator is missing an argument
Пример:
filter-error try [1 +]
** Script Error: Operator is missing an argument
** Where: 1 +
6.2.9 no-return (невозврат)
Функция, ожидающая, что блок вернет значение, но ничего не вернула. Например, при использовании функции while или until.
Сообщение:
Block did not return a value
Примеры:
filter-error try [ ; first block returns nothing
while [print 10][probe "ten"]
]
10
** Script Error: Block did not return a value
** Where: while [print 10] [probe "ten"]
filter-error try [
until [print 10] ; block returns nothing
]
10
** Script Error: Block did not return a value
** Where: until [print 10]
6.2.10 not-defined (не определено)
Используемое слово не было определено ни в каком контексте.
Сообщение:
[:arg1 "is not defined in this context"]
6.2.11 no-refine (без уточнения)
Была сделана попытка использовать уточнение функции, которой не было для этой функции.
Сообщение:
[:arg1 "has no refinement called" :arg2]
Пример:
f: func [/a] [if a [print "a"]]
filter-error try [f/b]
** Script Error: f has no refinement called b
** Where: f/b
6.2.12 invalid-path (неверный путь)
Была сделана попытка получить доступ к значению блока или объекта, используя путь, которого не было в этом блоке или объекте.
Сообщение:
["Invalid path value:" :arg1]
Пример:
blk: [a "a" b "b"]
filter-error try [print blk/c]
** Script Error: Invalid path value: c
** Where: print blk/c
obj: make object! [a: "a" b: "b"]
filter-error try [print obj/d]
** Script Error: Invalid path value: d
** Where: print obj/d
6.2.13 cannot-use (нельзя использовать)
Была сделана попытка выполнить операцию со значением несовместимого типа данных. Например, при попытке добавить строку к числу.
Сообщение:
["Cannot use" :arg1 "on" :arg2 "value"]
Пример:
filter-error try [1 + "1"]
** Script Error: Cannot use add on string! value
** Where: 1 + "1"
6.2.14 already-used (уже используется)
Была предпринята попытка присвоить псевдоним (alias) слову, которое уже было псевдонимом.
Сообщение:
["Alias word is already in use:" :arg1]
Пример:
alias 'print "prink"
filter-error try [alias 'probe "prink"]
** Script Error: Alias word is already in use: prink
** Where: alias 'probe "prink"
6.2.15 out-of-range (вне допустимого диапазона)
Была сделана попытка изменить недопустимый индекс серии.
Сообщение:
["Value out of range:" :arg1]
Пример:
blk: [1 2 3]
filter-error try [poke blk 5 "five"]
** Script Error: Value out of range: 5
** Where: poke blk 5 "five"
6.2.16 past-end
Была сделана попытка получить доступ к данным ряда за пределами длины ряда.
Сообщение:
Out of range or past end
Сообщение:
blk: [1 2 3]
filter-error try [print fourth blk]
** Script Error: Out of range or past end
** Where: print fourth blk
6.2.17 no-memory (без памяти)
Системе не хватило памяти при попытке завершить операцию.
Сообщение:
Not enough memory
6.2.18 wrong-denom (неправильный деном)
Была произведена математическая операция с денежными знаками двух разных номиналов. Например, при попытке прибавить 1 доллар США к 1,50 DEN.
Сообщение:
[:arg1 "not same denomination as" :arg2]
Пример:
filter-error try [US$1.50 + DM$1.50]
** Script Error: US$1.50 not same denomination as DM$1.50
** Where: US$1.50 + DM$1.50
6.2.19 bad-press (плохая пресса)
Была сделана попытка распаковать двоичное значение, которое было повреждено или не было сжатым форматом.
Сообщение:
["Invalid compressed data - problem:" :arg1]
Пример:
compressed: compress {some data}
change compressed "1"
filter-error try [decompress compressed]
** Script Error: Invalid compressed data - problem: -3
** Where: decompress compressed
6.2.20 bad-port-action (плохой порт-действие)
Была сделана попытка выполнить неподдерживаемое действие над портом. Например, при попытке использовать find на TCP-порту.
Сообщение:
["Cannot use" :arg1 "on this type port"]
6.2.21 needs (потребности)
Была предпринята попытка запустить сценарий, для которого требовалась либо новая версия REBOL, либо файл, который не удалось найти. Эта информация будет найдена в заголовке сценария REBOL.
Сообщение:
["Script needs:" :arg1]
6.2.22 locked-word (заблокированное слово)
Была сделана попытка изменить защищенное слово. Слово будет защищено функцией protect (защиты).
Сообщение:
["Word" :arg1 "is protected, cannot modify"]
Пример:
my-word: "data"
protect 'my-word
filter-error try [my-word: "new data"]
** Script Error: Word my-word is protected, cannot modify
** Where: my-word: "new data"
6.2.23 dup-vars
Была оценена функция, в которой в блоке спецификации было несколько вхождений слова. Например, если слово arg было определено как аргумент один и два.
Сообщение:
["Duplicate function value:" :arg1]
Пример:
filter-error try [f: func [a /local a][print a]]
** Script Error: Duplicate function value: a
** Where: func [a /local a] [print a]
6.3 Ошибки доступа
6.3.1 cannot-open (не открывается)
Нет доступа к файлу. Это может быть локальный или сетевой файл. Наиболее частая причина этой ошибки - несуществующий каталог.
Сообщение:
["Cannot open" :arg1]
Пример:
filter-error try [read %/c/path-not-here]
** Access Error: Cannot open /c/path-not-here
** Where: read %/c/path-not-here
6.3.2 not-open (не открыто)
Была сделана попытка использовать закрытый порт.
Сообщение:
["Port" :arg1 "not open"]
Сообщение:
p: open %file.txt
close p
filter-error try [copy p]
** Access Error: Port file.txt not open
** Where: copy p
6.3.3 already-open (уже открыт)
Была сделана попытка открыть (open) порт, который уже был открыт.
Сообщение:
["Port" :arg1 "already open"]
Пример:
p: open %file.txt
filter-error try [open p]
** Access Error: Port file.txt already open
** Where: open p
6.3.4 already-closed (уже закрыто)
Была предпринята попытка закрыть (close) уже закрытый порт.
Сообщение:
["Port" :arg1 "already closed"]
Пример:
p: open %file.txt
close p
filter-error try [close p]
** Access Error: Port file.txt not open
** Where: close p
6.3.5 invalid-spec (недействительная спецификация)
Была сделана попытка создать порт с помощью make, используя спецификацию, по которой порт не может быть построен.
Сообщение:
["Invalid port spec:" :arg1]
Пример:
filter-error try [p: make port! [scheme: 'naughta]]
** Access Error: Invalid port spec: scheme naughta
** Where: p: make port! [scheme: 'naughta]
6.3.6 socket-open (открыт сокет)
В операционной системе закончились выделенные сокеты.
Сообщение:
["Error opening socket" :arg1]
6.3.7 no-connect (без подключения)
Не удалось подключиться к другому хосту. Это общая ошибка, охватывающая ряд причин сбоя подключения. Когда станет известно больше информации о причине сбоя подключения, будет выдана более конкретная ошибка.
Сообщение:
["Cannot connect to" :arg1]
Пример:
filter-error try [read http://www.host.dom/]
** Access Error: Cannot connect to www.host.dom
** Where: read http://www.host.dom/
6.3.8 no-delete (запретить удаление)
Была предпринята попытка удалить файл (delete), который был заблокирован или защищен.
Сообщение:
["Cannot delete" :arg1]
Пример:
p: open %file.txt
filter-error try [delete %file.txt]
** Access Error: Cannot delete file.txt
** Where: delete %file.txt
6.3.9 no-rename (без переименования)
Была сделана попытка переименовать файл (rename), который был заблокирован или защищен.
Сообщение:
["Cannot rename" :arg1]
Пример:
p: open %file.txt
filter-error try [rename %file.txt %new-name.txt]
** Access Error: Cannot rename file.txt
** Where: rename %file.txt %new-name.txt
6.3.10 no-make-dir
Была сделана попытка создать каталог по пути к файлу, который не существует или был защищен от записи.
Сообщение:
["Cannot make directory" :arg1]
Пример:
filter-error try [make-dir %/c/no-path/dir]
** Access Error: Cannot make directory /c/no-path/dir/
** Where: m-dir path return path
6.3.11 timeout
Время ожидания ответа от другого хоста истекло. Этот тайм-аут устанавливается в атрибуте timeout порта.
Сообщение:
Network timeout
6.3.12 new-level (новый уровень)
В сценарии была сделана попытка изменить безопасность на более низкий уровень безопасности, в котором было отказано. Это означает, что всякий раз, когда сценарий запрашивает более низкие настройки безопасности, а пользователь отклоняет запрос, возникает эта ошибка.
Сообщение:
["Attempt to change security level to" :arg1]
Пример:
secure quit
filter-error try [secure none] ; denied request
secure none
6.3.13 security (безопасность)
Произошло нарушение безопасности. Это произойдет, когда будет сделана попытка получить доступ к файлу или сети, когда для параметра secure установлено значение throw.
Сообщение:
REBOL - Security Violation
Пример:
secure throw
filter-error try [open %file.txt]
** Access Error: REBOL - Security Violation
** Where: open %file.txt
secure none
6.3.14 invalid-path (неверный путь)
Использован неверный путь к файлу.
Сообщение:
["Bad file path:" :arg1]
Пример:
filter-error try [read %/]
6.4 Внутренние ошибки
6.4.1 bad-path (неверный путь)
Был оценен путь, который начинается с недопустимого слова.
Сообщение:
["Bad path:" arg1]
Пример:
path: make path! [1 2 3]
filter-error try [path]
** Internal Error: Bad path: 1
** Where: path
6.4.2 not-here (не здесь)
Была сделана попытка использовать функцию REBOL/Command или REBOL/View из REBOL/Core.
Сообщение:
[arg1 "not supported on your system"]
6.4.3 stack-overflow (переполнение стека)
Стек системной памяти переполнен при попытке выполнить операцию.
Сообщение:
["Stack overflow"]
Пример:
call-self: func [][call-self]
filter-error try [call-self]
** Internal Error: Stack overflow
** Where: call-self
6.4.4 globals-full (глобальное переполнение)
Превышено максимально допустимое количество определенных глобальных слов.
Сообщение:
["No more global variable space"]
|