lua 错误处理
语法错误
语法错误编译不能通过,通常是由程序使用不当引起
示例:nil与整数相加
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> a==2
false
-- a由于未赋值,默认为nil,不能和数值相加
> a+1
stdin:1: attempt to perform arithmetic on a nil value (global 'a')
stack traceback:
stdin:1: in main chunk
[C]: in ?
示例:语法缺少关键词
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> t={1,2,3,4,5,6}
-- 遍历表:关键词是in
> for key,value int pairs(t) print(key,value) end
stdin:1: 'in' expected near 'int'
-- 遍历表,缺少关键词do
> for key,value in pairs(t) print(key,value) end
stdin:1: 'do' expected near 'print'
-- 遍历表,正常输出
> for key,value in pairs(t) do print(key,value) end
1 1
2 2
3 3
4 4
5 5
6 6
运行错误
运行错误可通过编译,在运行时由于参数传递等原因报错
示例:函数参数不对导致运行报错
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> function fun(a,b) print(a+b) end
-- 传入1个参数,另一个参数没有赋值,默认为nil,nil不能与整数相加
> fun(1)
stdin:1: attempt to perform arithmetic on a nil value (local 'b')
stack traceback:
stdin:1: in function 'fun'
(...tail calls...)
[C]: in ?
-- 传入两个数值,可正常相加
> fun(1,2)
3
-- 字符串类型不能相加
> fun('a','b')
stdin:1: attempt to add a 'string' with a 'string'
stack traceback:
[C]: in metamethod 'add'
stdin:1: in function 'fun'
(...tail calls...)
[C]: in ?
assert 函数
assert(v, message):当v为false时,输出报错信息message
Raises an error if the value of its argument v is false (i.e., nil or false);
otherwise, returns all its arguments. In case of error, message is the error
object; when absent, it defaults to "assertion failed!"
* 当参数v是false时,输出错误信息,如果缺省message,默认输出"assertion failed!"
* 当参数v是true时,返回所有参数(v message)
示例
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
-- assert(false)
> assert(false)
stdin:1: assertion failed!
stack traceback:
[C]: in function 'assert'
stdin:1: in main chunk
[C]: in ?
-- assert(nil)
> assert(nil)
stdin:1: assertion failed!
stack traceback:
[C]: in function 'assert'
stdin:1: in main chunk
[C]: in ?
-- assert("nil")
> assert("nil")
nil
-- assert(2>1)
> assert(2>1)
true
-- assert(2<1,"2不小于1")
> assert(2<1,"2不小于1")
stdin:1: 2不小于1
stack traceback:
[C]: in function 'assert'
stdin:1: in main chunk
[C]: in ?
-- 输出v、message
> assert(1,"这是错误信息")
1 这是错误信息
> assert(0,"0不是false")
0 0不是false
error 函数
error(message, level):输出错误信息,该函数不会返回
Raises an error (see §2.3) with message as the error object.
This function never returns.
* 中止正在执行的程序,输出错误信息message,该函数不会返回
Usually, error adds some information about the error position
at the beginning of the message, if the message is a string.
* 通常,error函数会附加一些错误位置的信息到message头部
The level argument specifies how to get the error position.
With level 1 (the default), the error position is where the
error function was called.
* level=1(默认):为调用error位置(文件+行号)
Level 2 points the error to where the function that called
error was called; and so on.
* level=2:指出哪个调用error的函数的函数
Passing a level 0 avoids the addition of error position
information to the message.
* level=0:不添加错误位置信息
示例:level=0
huli@hudeMacBook-Pro ~ % cat error.lua
function fun(a,b)
error("出错了",0)
print(a+b)
end
fun(1+2)
-- 不添加错误位置信息
huli@hudeMacBook-Pro ~ % lua error.lua
lua: 出错了
stack traceback:
[C]: in function 'error'
error.lua:2: in function 'fun'
error.lua:6: in main chunk
[C]: in ?
示例:level=1(默认)
-- level=1
huli@hudeMacBook-Pro ~ % cat error2.lua
function fun2(a,b)
error("出错了",1)
print(a+b)
end
fun2(2+2)
-- 错误信息:前面添加文件(error2.lua)、error函数所在行号(2)
huli@hudeMacBook-Pro ~ % lua error2.lua
lua: error2.lua:2: 出错了
stack traceback:
[C]: in function 'error'
error2.lua:2: in function 'fun2'
error2.lua:6: in main chunk
[C]: in ?
示例:level=2
-- level=2
huli@hudeMacBook-Pro ~ % cat error3.lua
function fun3(a,b)
error("出错了",2)
print(a+b)
end
fun3(3+2)
-- 错误信息:文件名(error3.lua)、主函数调用了包含错误函数的函数所在行号(6)
huli@hudeMacBook-Pro ~ % lua error3.lua
lua: error3.lua:6: 出错了
stack traceback:
[C]: in function 'error'
error3.lua:2: in function 'fun3'
error3.lua:6: in main chunk
[C]: in ?
pcall 函数
pcall(function_name, arg, arg2, ...):以保护模式调用函数
Calls the function f with the given arguments in protected mode.
* 用给定的参数,以保护模式调用函数
This means that any error inside f is not propagated; instead,
pcall catches the error and returns a status code.
* 函数的错误信息不会传播,会被pall捕获,然后返回一个状态码(boolean值)
Its first result is the status code (a boolean), which is true
if the call succeeds without errors. In such case, pcall also
returns all results from the call, after this first result.
* 如果调用成功,状态码返回true
* 在true之后,pcall返回调用函数的所有结果
In case of any error, pcall returns false plus the error object.
Note that errors caught by pcall do not call a message handler
* 如果调用失败,pcall返回false,输出错误信息
示例:函数没有返回结果
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> function fun(a,b) print(a+b) end
-- 调用的韩素运行出错,输出状态码false,然后输出错误信息
> pcall(fun,1)
false stdin:1: attempt to perform arithmetic on a nil value (local 'b')
-- 执行函数,返回状态码,
-- 如果函数有返回结果,输出返回结果
> pcall(fun,1,2)
3
true
示例:函数有返回结果
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> function fun2(a,b) print(a+b) return a+b end
-- pcall(fun(1)):函数执行报错,随后pcall报错
> pcall(fun2(1))
stdin:1: attempt to perform arithmetic on a nil value (local 'b')
stack traceback:
stdin:1: in function 'fun2'
stdin:1: in main chunk
[C]: in ?
-- pcall(fun2,1):函数执行报错
> pcall(fun2,1)
false stdin:1: attempt to perform arithmetic on a nil value (local 'b')
-- pcall(fun2,1,2):函数正常执行,返回状态码、调用函数的返回结果
> pcall(fun2,1,2)
3
true 3
-- pcall(fun2(1,3),1,2):先执行函数,函数返回结果4 ==> pcall(4,1,2) pcall调用报错
> pcall(fun2(1,3),1,2)
4
false attempt to call a number value
-- pcall(fun(1,3)):先执行函数,函数返回结果4 == pcall(4),pcall
-- pcall只能调用函数,不能调用数字
> pcall(fun2(1,3))
4
false attempt to call a number value
xpcall 函数
xpcall(function_name, messageHandler, arg, arg2, ...):与pcall类似,多了messageHandler(错误处理函数)
This function is similar to pcall, except that
it sets a new message handler msgh.
示例:自定义错误处理函数
huli@hudeMacBook-Pro ~ % cat xpcall.lua
--被调用的函数
function fun(a,b)
print(a+b)
end
-- 自定义错误处理函数
function errorHandler(error)
print("error",error)
end
-- 调用函数
xpcall(fun, errorHandler, 1)
-- 执行脚本
huli@hudeMacBook-Pro ~ % lua xpcall.lua
error xpcall.lua:2: attempt to perform arithmetic on a nil value (local 'b')
示例:使用debug输出错误调用栈
huli@hudeMacBook-Pro ~ % cat xpcall2.lua
-- 调用的函数
function fun2(a,b)
print(a+b)
end
-- 错误处理函数
function errorHandler()
print(debug.traceback())
end
-- xpcall调用函数
xpcall(fun2, errorHandler, 1)
-- 执行脚本
huli@hudeMacBook-Pro ~ % lua xpcall2.lua
stack traceback:
xpcall2.lua:6: in function 'errorHandler'
xpcall2.lua:2: in function 'fun2'
[C]: in function 'xpcall'
xpcall2.lua:9: in main chunk
[C]: in ?