对于大多数应用而言,我们无需在 Lua
代码中做任何错误处理,应用程序本身会负责处理这类问题。所有 Lua
语言的行为都是由应用程序的一次调用而触发的,这类调用通常是要求 Lua
语言执行一段代码。如果执行中发生了错误,那么调用会返回一个错误代码,以便应用程序采取适当的行为来处理错误。当独立解释器中发生错误时,主循环会打印错误信息,然后继续显示提示符,并等待执行指定的命令。
不过,如果要在 Lua
代码中处理错误,那么就应该使用函数 pcall
(protected call)来封装代码。
假设要执行一段 Lua
代码并捕获执行中发生的所有错误,那么首先需要将这段代码封装到一个函数中,这个函数通常是一个匿名函数。之后,通过 pcall
来调用这个函数:
local ok, msg = pcall(function () -- some code if unexpected_condition then error() end -- some code print(a[i]) -- 潜在错误:'a'可能不是一个表 -- some code end) if ok then -- 执行被保护的代码时没有错误发生 -- 常规代码 else -- 执行被保护的代码时有错误发生:进行恰当的处理 -- 错误处理代码 end
函数 pcall
会以一种保护模式来调用它的第 1
个参数,以便捕获该函数执行中的错误。无论是否有错误发生,函数 pcall
都不会引发错误。如果没有错误发生,那么 pcall
返回 true
及被调用函数(作为 pcall
的第 1
个参数传入)的所有返回值;否则,则返回 false
及错误信息。
使用"错误信息"的命名方式可能会让人误解错误信息必须是一个字符串,因此称之为错误对象可能更好,这主要是因为函数 pcall
能够返回传递给 error
的任意 Lua
语言类型的值。
local status, err = pcall(function () error({code = 121}) end) print(err.code) --> 121
这些机制为我们提供了在 Lua
语言中进行异常处理的全部。我们可以通过 error
来抛出异常,然后用函数 pcall
来捕获异常,而错误信息则用来标识错误类型。