English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Обработка ошибок в процессе выполнения программы необходима, так как в процессе работы с файлами, передачей данных и вызовом web service могут возникать непредвиденные ошибки. Если не уделять внимания обработке информации, это может привести к утечке информации и невозможности выполнения программы.
В любом языке программирования необходима обработка ошибок. Типы ошибок включают:
Ошибки в грамматике
Ошибка выполнения
Ошибки в грамматике обычно возникают из-за неправильного использования компонентов программы (например, операторов, выражений). Пример:
-- test.lua файл a == 2
Результат выполнения кода выше будет:
lua: test.lua:2: '==' ожидается около
Как вы видите, в предыдущем примере出现了 синтаксическая ошибка, отличия между "=" и "==" очевидны. "=" это оператор присваивания, а "==" это сравнение.
Другой пример:
for a=1,10 print(a) end
Выполнение вышеуказанного кода приведет к следующим ошибкам:
lua: test2.lua:2: 'do' ожидается около 'print'
Синтаксическая ошибка проще, чем ошибка выполнения, так как ошибка выполнения не позволяет определить конкретную ошибку, а синтаксическая ошибка может быть быстро решена, как в предыдущем примере, достаточно добавить do после for-выражения:
for a=1,10 do print(a) end
Ошибка выполнения заключается в том, что программа может正常运行, но будет выводиться информация об ошибке. Например, из-за неправильного ввода параметров программа выдает ошибку при выполнении:
function add(a,b) возврат a+b end add(10)
Когда мы компилируем и запускаем следующий код, компиляция может быть успешной, но при выполнении могут возникнуть следующие ошибки:
lua: test2.lua:2: попытка выполнения арифметического действия с локальной переменной 'b' (значением nil) stack traceback: test2.lua:2: в функции 'add' test2.lua:5: в main блоке [C]: ?
В lua при вызове функции, даже если список фактических параметров и список формальных параметров не совпадают, вызов может быть успешным, избыточные параметры будут отброшены, а отсутствующие параметры будут заменены nil.
Вновь出现的错误 информации связано с тем, что параметр b был заменен nil после чего nil участвовал в арифметическом действии +.
например add внутри функции "return a+b" а не "print(a,b)" в этом случае, результат будет: "10 nil" не будет ошибок.
Мы можем использовать две функции: assert и error для обработки ошибок. Примеры приведены ниже:
local function add(a,b) assert(type(a) == "number", "a не является числом") assert(type(b) == "number", "b не является числом") возврат a+b end add(10)
Выполнение вышеуказанного кода приведет к следующим ошибкам:
lua: test.lua:3: b не является числом stack traceback: [C]: в функции 'assert' test.lua:3: в local 'add' test.lua:6: в главном блоке [C]: в ?
Пример: если assert сначала проверяет первый параметр, если нет проблем, assert не делает ничего; в противном случае, assert выбрасывает ошибку с второго параметра в качестве сообщения об ошибке.
Грамматический формат:
error (message [, level])
Функция:终止 выполняющийся функцию и вернуть содержимое сообщения в качестве ошибки (функция error никогда не возвращает)
Обычно error добавляет информацию о положении ошибки в начале сообщения.
Параметр Level указывает на получение информации о положении ошибки:
Level=1[по умолчанию]: Информация о положении вызова error (файл + номер строки)
Level=2: Указать функцию, которая вызвала error
Level=0: Не добавлять информацию о положении ошибки
Обработка ошибок в Lua может выполняться с помощью функции pcall (protected call), чтобы 包装 код для выполнения.
pcall принимает функцию и параметры, которые нужно передать последней, и выполняет её. Результат выполнения: с ошибкой, без ошибки; возвращается true или false, errorinfo.
Грамматический формат:
if pcall(function_name, ...) -- Нет ошибок else -- Некоторые ошибки end
Пример:
pcall(function(i) print(i) end, 33) 33 true pcall(function(i) print(i) error('error..') end, 33) 33 false stdin:1: error..
Здесь обратите внимание на логическую оценку возвращаемого значения:
function f() return false, 2 end if f() then print '1' else print '0' end 0
pcall вызывается в "защитном режиме" для первого параметра, поэтому pcall может улавливать любые ошибки, возникающие в процессе выполнения функции.
Обычно, когда возникает ошибка, мы хотим получить больше информации о调试, а не только положение ошибки. Но при возвращении pcall часть содержимого стека вызовов уже уничтожена.
Lua предоставляет функцию xpcall, которая принимает второй параметр - функцию обработки ошибок. При возникновении ошибки Lua вызывает функцию обработки ошибок до расширения стека (unwind), что позволяет использовать библиотеку debug для получения дополнительной информации о ошибке.
Библиотека debug предоставляет два общих функции обработки ошибок:
debug.debug: предоставляет Lua-подсказку, позволяющую пользователю проверить причину ошибки
debug.traceback: создает расширенное сообщение об ошибке на основе стека вызовов
>=xpcall(function(i) print(i) error('error..') end, function() print(debug.traceback()) end, 33) 33 stack traceback: stdin:1: в функции <stdin:1> [C]: в функции 'error' stdin:1: в функции <stdin:1> [C]: в функции 'xpcall' stdin:1: в головном блоке [C]: в ? false nil
Пример использования xpcall 2:
function myfunction () n = n/nil end function myerrorhandler( err ) print( "ERROR:", err ) end status = xpcall( myfunction, myerrorhandler ) print( status)
Выполнение вышеуказанного кода приведет к следующим ошибкам:
ERROR: test2.lua:2: попытка выполнить арифметическое операция с глобальной 'н' (пустое значение) false