第一版是針對 Lua 5.0 編寫的。雖然在很大程度上仍然適用於後續版本,但仍有一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您還可以 贊助 Lua 專案


8.5 – 錯誤訊息和追蹤

雖然您可以使用任何類型的值作為錯誤訊息,但通常錯誤訊息是描述錯誤原因的字串。當發生內部錯誤(例如嘗試索引非表格值)時,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)加上行號(範例中的 1)。

error 函式有一個額外的第二個參數,它會提供應該回報錯誤的層級;使用它,您可以責怪其他人造成錯誤。例如,假設您撰寫一個函式,它的第一個任務是檢查是否正確呼叫它

    function foo (str)
      if type(str) ~= "string" then
        error("string expected")
      end
      ...
    end
然後,有人使用錯誤的引數呼叫您的函式
    foo({x=1})
Lua 會指向您的函式---畢竟,是 foo 呼叫 error---而不是真正的罪魁禍首,呼叫者。要修正這個問題,您會通知 error 您回報的錯誤發生在呼叫層級中的第 2 層(第 1 層是您自己的函式)
    function foo (str)
      if type(str) ~= "string" then
        error("string expected", 2)
      end
      ...
    end

經常地,當錯誤發生時,我們想要比錯誤發生位置更多的除錯資訊。至少,我們想要一個追蹤,顯示導致錯誤的完整呼叫堆疊。當 pcall 回傳其錯誤訊息時,它會銷毀堆疊的一部分(從它到錯誤點的那一部分)。因此,如果我們想要一個追蹤,我們必須在 pcall 回傳之前建立它。為了做到這一點,Lua 提供了 xpcall 函式。除了要被呼叫的函式之外,它接收一個第二個引數,一個錯誤處理函式。在錯誤的情況下,Lua 會在堆疊展開之前呼叫那個錯誤處理函式,這樣它可以使用除錯函式庫來收集任何它想要的關於錯誤的額外資訊。兩個常見的錯誤處理函式是 debug.debug,它給你一個 Lua 提示,這樣你就可以自己檢查在錯誤發生時發生了什麼(稍後我們將在討論除錯函式庫時看到更多關於它的內容);以及 debug.traceback,它建立一個帶有追蹤的延伸錯誤訊息。後者是獨立解釋器用來建立其錯誤訊息的函式。你也可以在任何時候呼叫 debug.traceback 來取得目前執行的追蹤

    print(debug.traceback())