在Lua中,对于大多数程序都不用作任何错误处理,应用程序本身会负责这类问题。

所有的Lua活动都是由应用程序的一次调用开始的,这类调用要求Lua执行一个程序块。

执行过程中发生了错误,此调用会返回一个错误代码(nil ),这样应用程序就能采取适当的行动来处理。

如果需要在Lua中处理错误,则必须使用函数pcall来包装需要执行的代码。

假设在执行一段Lua代码时,捕获所有执行中引发的错误,那么第一步就是将这段代码封装到一个匿名函数中

然后用pcall去调用这个函数:

  1. local ok,msg = pcall(function ()
  2. <some code>
  3. if unexcepted then error() end
  4. <some code>
  5. print(a[i]) --引发错误,a可能不是一个talbe
  6. <some code >
  7. end)
  8.  
  9. if ok then -- 没有错误发生
  10. <regular code >
  11. else
  12. <error handling code > --保护模式代码引发一个错误,需要app引起注意
  13. end

如果function运行过程中没有发生错误,pcall返回true,和一些返回值。

否则返回false,和错误消息。

传给error函数的错误消息不一定非得是字符串,它可以是任意的lua值 。这些值也会成为pcall的返回值。

  1. local status,err = pcall( function() error({ code = }) end ) --传给error的是table
  2. print(err.code) --> 121

有了这些机制,就可以完成所有的异常处理。通过使用error来抛出一个异常或使用pcall来捕获异常。错误消息

则可以标识出错误类型或内容。

虽然错误消息可以是任意值,但是通常使用字符串去描述什么样的错误。

当发生内部错误时,Lua就抛出一个错误消息;其他时候,错误消息就是传递给error函数的值。

只要错误消息是一个字符串,Lua就会附加一些关于错误发生位置的信息(包含文件名比如stdin,及行号)。

  1. local status,err = pcall(function () a = "a" + end)
  2. print(err) --> stdin:1: attempt to perform arithmetic on a string value
  3. local status,err = pcall(function() error("my error") end)
  4. print(err) -->stdin:1: my error

error函数还有第二个附加参数level,用于指出应由调用层级中的哪个(层)函数来报告当前的错误。

也就是说明了谁应该为此错误负责。比如一个函数,它的功能是检查传入的参数是否正确:

  1. function foo (str)
  2. if type(str) ~= "string" then
  3. error("string expected")
  4. end
  5. <come code>
  6. end

然后有人这样传入错误参数地去调用:

  1. foo({x=})

由于foo是调用了error,所以Lua会认为是函数发生了错误。但实际上却是foo的调用者造成的错误。

为了纠正这个问题,就要告知error函数错误是发生在调用层级的第二层中(第一层是读函数)。

  1. function foo(str)
  2. if type(str) ~= "string" then
  3. error("string expected",)
  4. end
  5. <come code>
  6. end

通常发生错误时,我们希望得到更多的调试信息。比如完整的调用栈,追溯到发生错误时的函数调用。

当pcall返回其错误信息时,它已经销毁了调用栈的部分内容(也就是从pcall到错误发生点的这部分调用)。

为此,我们必须在调用pcall之前保存好完整的栈信息。

xpcall很好地解决了这个问题。它接收第二个参数,一个消息处理函数。

一旦发生错误,Lua就会在调用栈展开前调用它,所以可以在这个函数中使用

debug lib去获取关于错误的额外信息了。

Lua的调试库提供了两个通用消息处理函数:

debug.debug:提供一个提示符,让用户检查错误的原因

debug.traceback:它会根据调用栈来构建一个扩展的错误消息。也可以在任何时候调用这个函数来获取当前执行的调用栈:

  1. print (debug.trackback())

chapter8_4 错误处理的更多相关文章

  1. 航空概论(历年资料,引之百度文库,PS:未调格式,有点乱)

    航空航天尔雅 选择题1. 已经实现了<天方夜谭>中的飞毯设想.—— A——美国2. 地球到月球大约—— C 38 万公里3. 建立了航空史上第一条定期空中路线—— B——德国4. 对于孔明 ...

  2. 日期格式代码出现两次的错误 ORA-01810

    错误的原因是使用了两次MM . 一.Oracle中使用to_date()时格式化日期需要注意格式码 如:select to_date('2005-01-01 11:11:21','yyyy-MM-dd ...

  3. ASP.NET Core应用的错误处理[3]:ExceptionHandlerMiddleware中间件如何呈现“定制化错误页面”

    DeveloperExceptionPageMiddleware中间件利用呈现出来的错误页面实现抛出异常和当前请求的详细信息以辅助开发人员更好地进行纠错诊断工作,而ExceptionHandlerMi ...

  4. ASP.NET Core应用的错误处理[2]:DeveloperExceptionPageMiddleware中间件如何呈现“开发者异常页面”

    在<ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式>中,我们通过几个简单的实例演示了如何呈现一个错误页面,这些错误页面的呈现分别由三个对应的中间件来完成,接下来我们将 ...

  5. 实时的.NET程序错误监控产品Exceptionless

    Exceptionless可以对ASP.NET, Web API, WebForms, WPF, Console, 和 MVC 应用提供错误监控.上传.报表服务.使用时需要在Exceptionless ...

  6. 一个粗心的Bug,JSON格式不规范导致AJAX错误

    一.事件回放  今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里. 当时正在联调一个项目,由于后端没有提供数据接口,于是我直接本地建立了一个 json ...

  7. SQL Server 致程序员(容易忽略的错误)

    标签:SQL SERVER/MSSQL/DBA/T-SQL好习惯/数据库/需要注意的地方/程序员/容易犯的错误/遇到的问题 概述 因为每天需要审核程序员发布的SQL语句,所以收集了一些程序员的一些常见 ...

  8. C# - 值类型、引用类型&走出误区,容易错误的说法

    1. 值类型与引用类型小总结 1)对于引用类型的表达式(如一个变量),它的值是一个引用,而非对象. 2)引用就像URL,是允许你访问真实信息的一小片数据. 3)对于值类型的表达式,它的值是实际的数据. ...

  9. 记一个mvn奇怪错误: Archive for required library: 'D:/mvn/repos/junit/junit/3.8.1/junit-3.8.1.jar' in project 'xxx' cannot be read or is not a valid ZIP file

    我的maven 项目有一个红色感叹号, 而且Problems 存在 errors : Description Resource Path Location Type Archive for requi ...

随机推荐

  1. html使用css让文字多行超出部分用省略号三个点显示的方法案例

    text-overflow: -o-ellipsis-lastline;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-w ...

  2. metrics实践 (metrics-spring)

    这里主要介绍metrics与spring集成的使用方式. 1  添加maven依赖 <dependency> <groupId>com.ryantenney.metrics&l ...

  3. 利用before、after制作提示框

    提示框由两部分组成,框+箭头,箭头则利用伪元素before.after写成. 根据提示框的样式可以看出,上面的箭头由两部分组成:灰色大箭头+蓝色小箭头,蓝色嵌套在灰色里面,于是箭头就有了边框,整体搭配 ...

  4. 移动app安全测试

    安全方面逐渐转向app安全,服务端app安全测试基本上跟常规的web方面挖掘差不多,只是增加了一个反编译或抓包的过程. 参考文献: http://drops.wooyun.org/tips/749 h ...

  5. C# 语言规范_版本5.0 (第6章 转换)

    1. 转换 转换(conversion) 使表达式可以被视为一种特定类型.转换可导致将给定类型的表达式视为具有不同的类型,或其可导致没有类型的表达式获得一种类型.转换可以是隐式的 (implicit) ...

  6. VM10下Ubuntu无法安装vim的问题

    今天在VM10下重装了Ubuntu14.10,安装vim时发现如下问题 谷歌了一下,终于找到一种方法解决. 终端下: sudo vi /etc/apt/source.list 该命令将用vi打开一个文 ...

  7. 用DriverBackUp备份了文件 装好系统后怎么把备份的驱动文件还原

    1.打开DriverBackUp 2.菜单栏选择Restore 3.选择open backup file 4.找到备份文件位置,并选择.bki后缀的文件 5.点击"打开" 6.勾选 ...

  8. JS:JSP Servlet

    Servlet 是在服务器上运行的小程序.这个词是在 Java applet的环境中创造的,Java applet 是一种当作单独文件跟网页一起发送的小程序,它通常用于在客户端运行,结果得到为用户进行 ...

  9. HDU 4451 Dressing

    HDU 4451 Dressing 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=4451 Description Wangpeng has ...

  10. Kinetis学习笔记(一)——基于KSDK 2.0