Коды ошибок базы данных
В текущей версии бинарного протокола в ответы сервера не включены сообщения об ошибках, которые как правило, содержат больше информации, чем коды ошибок. Само сообщение может содержать имя файла, подробное описание причины или код ошибки операционной системы. Однако все такие сообщения регистрируются в журнале ошибок. Ниже приведены общие описания некоторых распространенных кодов. Полный список ошибок можно найти в файле errcode.h в исходном дереве.
Список кодов ошибок
ER_NONMASTER | (Репликация) Экземпляр сервера не может вносить изменения в данные, если он не является мастером. |
ER_ILLEGAL_PARAMS | Недопустимые параметры. Некорректное протокольное сообщение. |
ER_MEMORY_ISSUE | Нехватка оперативной памяти: достижение предела памяти memtx_memory. |
ER_WAL_IO | Запись на диск не удалась. Может означать, что не удалось записать изменение в журнале упреждающей записи. Некоторая ошибка на диске. |
ER_KEY_PART_COUNT | Количество частей ключа не совпадает с количеством частей индекса |
ER_NO_SUCH_SPACE | Указанный спейс отсутствует. |
ER_NO_SUCH_INDEX | Указанного индекса нет в указанном спейсе. |
ER_PROC_LUA | Возникла ошибке в Lua-процедуре. |
ER_FIBER_STACK | При создании нового файбера был достигнут предел рекурсии. Обычно это указывает на то, что хранимая процедура слишком часто рекурсивно вызывает себя. |
ER_UPDATE_FIELD | Возникла ошибка во время обновления поля. |
ER_TUPLE_FOUND | В уникальном индексе есть повторяющийся ключ. |
Обработка ошибок
Ниже представлены несколько процедур для более надежного вызова Lua-функций в случае ошибок, в частности, ошибок базы данных.
Вызов с помощью pcall.
Используйте механизмы Lua для «Обработки ошибок и исключений», в частностиpcall
. То есть вместо простого вызова функции с помощьюbox.space.имя-спейса:имя-функции()
выполнитеif pcall(box.space.имя-спейса.имя-функции, box.space.имя-спейса) ...
Для некоторых функций модуля box в Tarantool’е pcall также вернет описание ошибки, включая имя файла и номер строки в исходном коде Tarantool’а. Например:x, y = pcall(function() box.schema.space.create('') end)
y:unpack()
Чтобы увидеть применение pcall в приложении, см. практическое задание Подсчет суммы по JSON-полям во всех кортежах.
Проверка и вызов ошибки с помощью box.error.
В модуле box.error предусмотрена функция box.error(code, errtext [, errtext …]), чтобы создать ошибку и передать ее.
Чтобы найти последнюю ошибку, в модуле box.error предусмотрена функция box.error.last(). (Также можно найти текст последней ошибки операционной системы для определенной функции – errno.strerror([code]).)
Запись в журнал.
Записывайте сообщения в журнал с помощью модуля log.
И отфильтровывайте автоматически созданные сообщения с помощью конфигурационного параметра log.
Как правило, встроенные функции Tarantool’а, которые предназначены для возврата объектов, вернут либо объект, либо нулевое значение nil, либо Lua-ошибку. Например, рассмотрим программу fio_read.lua из рекомендаций по разработке:
#!/usr/bin/env tarantool
local fio = require('fio')
local errno = require('errno')
local f = fio.open('/tmp/xxxx.txt', {'O_RDONLY' })
if not f then
error("Failed to open file: "..errno.strerror())
end
local data = f:read(4096)
f:close()
print(data)
После вызова функции, который может не сработать, как fio.open() выше, обычно можно увидеть такой синтаксис, как if not f then ...
или if f == nil then ...
, который проверяет на типичные отказы. Но если есть ошибка синтаксиса, например, fio.opex вместо fio.open, то появится Lua-ошибка, и f не изменится. Если речь идет о проверке таких очевидных ошибок, программист вероятно будет использовать pcall().
Все функции в модулях Tarantool’а должны работать таким образом, если в руководстве явно не говорится об обратном.