Lua 错误处理
错误类型有:
- 语法错误
- 运行错误
一、语法错误
语法错误通常是由于对程序的组件(如运算符、表达式)使用不当引起的。
实例:
for a= 1,10 print(a) end
执行以上程序会出现如下错误:
lua: test2.lua:2: 'do' expected near 'print'
二、运行错误
运行错误是程序可以正常执行,但是会输出报错信息。
实例:
function add(a,b) return a+b end add(10)
当我们编译运行以下代码时,编译是可以成功的,但在运行的时候会产生如下错误:
lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value) stack traceback: test2.lua:2: in function 'add' test2.lua:5: in main chunk [C]: ?
lua 里调用函数时,即使实参列表和形参列表不一致也能成功调用,多余的参数会被舍弃,缺少的参数会被补为 nil。
以上报错信息是由于参数 b 被补为 nil 后,nil 参与了 + 运算。
假如 add 函数内不是 “return a+b” 而是 “print(a,b)” 的话,结果会变成 “10 nil” 不会报错。
三、错误处理
我们可以使用两个函数:assert 和 error 来处理错误。
1. assert
function add(a, b) assert(type(a) == "number", "a is not a number") assert(type(b) == "number", "b is not a number") return a + b end add(10)
执行以上程序会出现如下错误:
lua: test.lua:3: b 不是一个数字 stack traceback: [C]: in function 'assert' test.lua:3: in local 'add' test.lua:6: in main chunk [C]: in ?
实例中assert首先检查第一个参数,若没问题,assert不做任何事情;否则,assert以第二个参数作为错误信息抛出。
2. error
语法格式:
error (message [, level])
**功能:**终止正在执行的函数,并返回message的内容作为错误信息(error函数永远都不会返回)
通常情况下,error会附加一些错误位置的信息到message头部。
Level参数指示获得错误的位置:
Level=1(默认):为调用error位置(文件+行号)
Level=2:指出哪个调用error的函数的函数
Level=0:不添加错误位置信息
function div(a, b) if b == 0 then error('? / 0') else print(a / b) end end div(10, 0)
error错误:
/usr/local/bin/lua: ./1_test.lua:5: ? / 0 ..................
3. pcall 和 xpcall、debug
pcall()函数: 如果程序发生错误,不想让程序停止。
pcall():接收一个函数和要传递给后者的参数,并执行。
pcall()有两个返回值:
- 是否正确
- 错误原因
语法格式如下:
if pcall(function_name, ….) then -- 没有错误 else -- 一些错误 end
示例:
local a, b = pcall(function() print(a[1]) end) print(a) -- false print(b) -- attempt to index global 'a' (a nil value)
local a, b = pcall(function(a, b) return a / b end, 2, 0) print(a, b) -- true inf
这里有个问题,传a, b = 2, 0,但是并不会报错。即同上一段代码一样,能运行出inf,返回true。
但是改成只传一个参a,返回a/0,则会报错。
if pcall(function(a, b) return a / b end, 2, 0) then print("no error") else print('div 0') end
pcall以一种"保护模式"来调用第一个参数,因此pcall可以捕获函数执行中的任何错误。
但是lua还提供xpcall。
xpcall和pcall的区别最大的地方是,可以传递一个出错的函数,xpcall接收第二个参数是一个错误处理函数,可以在这个函数中使用debug库来获取关于错误的额外信息了。
debug库提供了两个通用的错误处理函数:
**debug.debug:**提供一个Lua提示符,让用户来检查错误的原因
**debug.traceback:**根据调用桟来构建一个扩展的错误消息
function add(a, b) return a + b end function errorFunc(err) print('error :', err) print(debug.traceback()) end local res, info = xpcall(add, errorFunc, 1, nil) print(res) print(info)
error : ./3_test.lua:4: attempt to perform arithmetic on local 'b' (a nil value) false nil