【Lua 入门基础篇(十一)】错误处理

简介: 笔记

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()有两个返回值:

  1. 是否正确
  2. 错误原因

语法格式如下:

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
相关文章
|
NoSQL 安全 Java
Redis从入门到精通之Lua 脚本
Lua 是一种轻量级的脚本语言,被广泛应用于游戏开发、嵌入式系统、Web 开发、科学计算等领域。Redis 内置了 Lua 解释器,使得用户可以通过编写 Lua 脚本来扩展 Redis 的功能。在 Redis 中,可以使用 EVAL 和 EVALSHA 命令执行 Lua 脚本。
811 8
Redis从入门到精通之Lua 脚本