zoukankan      html  css  js  c++  java
  • chapter8_4 错误处理

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

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

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

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

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

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

    local ok,msg = pcall(function ()
        <some code>
        if unexcepted then error() end
        <some code>
        print(a[i])    --引发错误,a可能不是一个talbe
        <some code >
    end)
    
    if ok then -- 没有错误发生
        <regular code >
    else
        <error handling code > --保护模式代码引发一个错误,需要app引起注意
    end

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

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

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

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

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

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

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

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

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

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

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

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

    function foo (str)
        if type(str) ~= "string" then
            error("string expected")
        end
            <come code>
        end

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

    foo({x=1})

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

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

    function foo(str)
        if type(str) ~= "string" then
            error("string expected",2)
        end
            <come code>
    end

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

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

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

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

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

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

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

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

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

    print (debug.trackback())
  • 相关阅读:
    linux socket c : send data when socket close—SIGPIPE, Broken pipe
    (OK) server-client-pthread-c language
    (OK) Linux epoll模型—socket epoll server client chat—pthread
    (OK) pthread—epoll-loops-on-disconnection-of-a-client—server
    (OK) Linux epoll模型—socket epoll server client chat
    (OK) 刘姐实验中的大数据分析—awk—paste—system
    (OK) cBPM-CentOS—wrapped by fastcgi—files—executing commands
    (Not OK) 在CentOS7—编译nginx—for—Android—Makefile
    (Not OK) 在CentOS7—编译nginx—for—Android
    (OK) 在CentOS7—编译OpenSSL 静态库—for—Android
  • 原文地址:https://www.cnblogs.com/daiker/p/5818163.html
Copyright © 2011-2022 走看看