1. 程式人生 > >lua錯誤資訊和回跟蹤(Tracebacks)

lua錯誤資訊和回跟蹤(Tracebacks)

雖然你可以使用任何型別的值作為錯誤資訊,通常情況下,我們使用字串來描述遇到的錯誤。如果遇到內部錯誤(比如對一個非table的值使用索引下標訪問)Lua將自己產生錯誤資訊,否則Lua使用傳遞給error函式的引數作為錯誤資訊。不管在什麼情況下,Lua都儘可能清楚的描述問題發生的緣由。

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

例子中錯誤資訊給出了檔名(stdin)與行號。

函式error還可以有第二個引數,表示錯誤發生的層級。比如,你寫了一個函式用來檢查“error是否被正確呼叫”:

function foo (str)

    if type(str) ~= "string" then

       error("string expected")

    end

    ...

end

可有人這樣呼叫此函式:

foo({x=1})

Lua會指出發生錯誤的是foo而不是error,實際上,錯誤是呼叫error時產生的。為了糾正這個問題,修改前面的程式碼讓error報告錯誤發生在第二級(你自己的函式是第一級)如下:

function foo (str)

    if type(str) ~= "string" then

       error("string expected", 2)

    end

    ...

end

當錯誤發生的時候,我們常常希望瞭解詳細的資訊,而不僅是錯誤發生的位置。若能瞭解到“錯誤發生時的棧資訊”就好了,但pcall返回錯誤資訊時,已經釋放了儲存錯誤發生情況的棧資訊。因此,若想得到tracebacks,我們必須在pcall返回以前獲取。Lua提供了xpcall來實現這個功能,xpcall接受兩個引數:呼叫函式、錯誤處理函式。當錯誤發生時,Lua會在棧釋放以前呼叫錯誤處理函式,因此可以使用debug庫收集錯誤相關資訊。有兩個常用的debug處理函式:debug.debug和debug.traceback,前者給出Lua的提示符,你可以自己動手察看錯誤發生時的情況;後者通過traceback建立更多的錯誤資訊,也是控制檯直譯器用來構建錯誤資訊的函式。你可以在任何時候呼叫debug.traceback獲取當前執行的traceback資訊:

print(debug.traceback())