Lua 错误处理
程序难免不会出各种小错大错,能够在程序出错之后进行处理是非常重要的
程序运行中错误处理是必要的,在我们进行文件操作,数据转移及 web service 调用过程中都会出现不可预期的错误。 如果不注重错误信息的处理,就会照成信息泄露,程序无法运行等情况。
任何程序语言中,都需要错误处理。
错误类型有:
- 语法错误
- 运行错误
1. 语法错误
语法错误通常是由于对程序的组件(如运算符、表达式)使用不当引起的
-- !/usr/bin/lua -- -*- encoding:utf-8 -*- -- filename: main.lua -- author: 简单教程(www.twle.cn) -- Copyright © 2015-2065 www.twle.cn. All rights reserved. age == 18
运行以上 Lua 脚本,输出结果如下:
$ lua main.lua
lua: main.lua:11: syntax error near '=='
正如结果显示的那样,a==2
出现了语法错误
一个 "=" 号跟两个 "=" 号是有区别的:
一个 "=" 是赋值表达式,两个 "=" 是比较运算
范例 2: Lua 中的语法错误
-- !/usr/bin/lua -- -*- encoding:utf-8 -*- -- filename: main.lua -- author: 简单教程(www.twle.cn) -- Copyright © 2015-2065 www.twle.cn. All rights reserved. for a= 1,10 print(a) end
运行以上 Lua 脚本,输出结果如下:
$ lua main.lua lua: main.lua:12: 'do' expected near 'print'
范例程序少了 do
语句,所以出现语法错误了
语法错误比程序运行错误更简单,运行错误无法定位具体错误,而语法错误我们可以很快的解决,例如以上范例中,我们只要在for语句下添加 do 即可:
for a= 1,10 do print(a) end
运行错误
运行错误是程序可以正常编译和运行,但是会输出报错信息。
下面的代码由于函数参数输入错误,程序执行时就会报错
-- !/usr/bin/lua -- -*- encoding:utf-8 -*- -- filename: main.lua -- author: 简单教程(www.twle.cn) -- Copyright © 2015-2065 www.twle.cn. All rights reserved. function mul(a,b) return a * b end mul(10)
编译以上范例,是可以编译成功的,但在运行时就会产生错误,产生错误的原因是因为少传了 b
参数
$ lua main.lua lua: main.lua:12: attempt to perform arithmetic on a nil value (local 'b') stack traceback: main.lua:12: in function 'mul' main.lua:15: in main chunk [C]: i
错误处理
Lua 语言提供了两个函数:assert
和 error
用来预防和处理错误
Lua 语言中的 assert 函数用于检查表达式
-- !/usr/bin/lua -- -*- encoding:utf-8 -*- -- filename: main.lua -- author: 简单教程(www.twle.cn) -- Copyright © 2015-2065 www.twle.cn. All rights reserved. function mul(a,b) assert(type(a) == "number", "a 不是一个数字") assert(type(b) == "number", "b 不是一个数字") return a * b end mul(5)
运行以上 Lua 脚本,输出结果如下:
$ lua main.lua lua: main.lua:13: b 不是一个数字 stack traceback: [C]: in function 'assert' main.lua:13: in function 'mul' main.lua:17: in main chunk [C]: in ?
范例代码中的 assert
函数首先检查第一个参数,若没问题,assert 不做任何事情;
否则,assert 以第二个参数作为错误信息抛出
Lua 语言中的 error 函数用于产生错误
error 函数语法格式如下:
error (message [, level])
error 函数终止正在执行的函数,并直接输出 message 的内容作为错误信息
通常情况下,error 函数会附加一些错误位置的信息到 message 头部
注意
error 函数永远都不会返回
Level参数指示错误的位置:
错误级别 | 描述 |
---|---|
Level=1 默认 | 为调用 error 位置(文件+行号) |
Level=2 | 指出哪个调用 error 的函数的函数 |
Level=0 | 不添加错误位置信息 |
范例
-- !/usr/bin/lua -- -*- encoding:utf-8 -*- -- filename: main.lua -- author: 简单教程(www.twle.cn) -- Copyright © 2015-2065 www.twle.cn. All rights reserved. function throw_error() error("error 函数用来抛出错误", 1) end throw_error()
运行以上 Lua 脚本,产生错误如下
$ lua main.lua lua: main.lua:11: error 函数用来抛出错误 stack traceback: [C]: in function 'error' main.lua:11: in function 'throw_error' main.lua:15: in main chunk [C]: in ?
pcall 和 xpcall、debug
Lua 语言中可以使用 pcall(protected call) 函数来包装需要执行的代码
pcall(protected call) 函数 想当于其它语言中的 try...catch
模块
pcall 函数语法格式如下
if pcall(function_name, ….) then -- 没有错误 else -- 一些错误 end
pcall 函数接收一个函数和要传递个后者的参数,并执行
pcall 函数的执行结果:有错误、无错误,返回值 true 或者或 false , errorinfo
范例
pcall 运行成功返回 true
> =pcall(function(i) print(i) end, 17) 17 true
pcall 运行失败则返回 2 个参数,一个是 false
,另一个是产生的错误信息
> =pcall(function(i) print(i) error('error..') end, 17) 17 false stdin:1: error..
> function f() return false,2 end > if f() then print '1' else print '0' end 0
pcall 函数以一种 保护模式 来调用第一个参数,因此 pcall 可以捕获函数执行中的任何错误。
xpcall 函数
通常在错误发生时,希望落得更多的调试信息,而不只是发生错误的位置。 但 pcall 返回时,它已经销毁了调用桟的部分内容。
Lua提供了 xpcall 函数,xpcall 接收第二个参数——一个错误处理函数,当错误发生时,Lua会在调用桟展看(unwind)前调用错误处理函数,于是就可以在这个函数中使用debug库来获取关于错误的额外信息了。
debug 库提供了两个通用的错误处理函数:
- debug.debug:提供一个Lua提示符,让用户来价差错误的原因
- debug.traceback:根据调用桟来构建一个扩展的错误消息
> =xpcall(function(i) print(i) error('error..') end, function() print(debug.traceback()) end, 17) 17 stack traceback: stdin:1: in function< 1 > [C]: in function 'error' stdin:1: in function< 1 > [C]: in function 'xpcall' stdin:1: in main chunk [C]: in ? false nil
范例 : xpcall 使用
-- !/usr/bin/lua -- -*- encoding:utf-8 -*- -- filename: main.lua -- author: 简单教程(www.twle.cn) -- Copyright © 2015-2065 www.twle.cn. All rights reserved. function myfunc () n = n/nil end function errorhandler( err ) print( "ERROR:", err ) end status = xpcall( myfunc, errorhandler ) print( status)
运行以上 Lua 脚本,产生错误如下:
$ lua main.lua ERROR: main.lua:11: attempt to perform arithmetic on a nil value (global 'n') false