Lua 错误处理

程序难免不会出各种小错大错,能够在程序出错之后进行处理是非常重要的

程序运行中错误处理是必要的,在我们进行文件操作,数据转移及 web service 调用过程中都会出现不可预期的错误。 如果不注重错误信息的处理,就会照成信息泄露,程序无法运行等情况。

任何程序语言中,都需要错误处理。

错误类型有:

  1. 语法错误
  2. 运行错误

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 语言提供了两个函数:asserterror 用来预防和处理错误

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
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.