mar*_*son 5 error-handling lua lua-5.1
Lua 5.1 的 API 提供了一个error()函数,它接受一个字符串(错误消息)和一个“级别”。
我的理解是level,可以让您向上移动调用堆栈,这样您就可以提供更好的错误报告,尤其是在将模块作为 API 提供时。
例如,假设用户api_function(x)使用进行呼叫x = nil。这将是一个错误,但 API 直到深入了解其代码后才知道。
它可能会导致以下调用堆栈:
api_function(x) : user_file.lua:30
-> api_function : api.lua:20
-> some_function : api.lua:250
-> handle_when_x_string : api_string.lua:20
-> error("value is nil") : api_string.lua:66
Run Code Online (Sandbox Code Playgroud)
正如所写的,用户会看到类似的东西api_string.lua:66 error: value is nil,而他们真正想要看到的“不错”的错误,user_file.lua:30 error: value is nil。(“这个错误是我的错还是 API 中的错误?”)
现在,我们可以将代码更改为“弹出调用堆栈”,
api_function(x) : user_file.lua:30
-> api_function : api.lua:20
-> some_function : api.lua:250
-> handle_when_x_string : api_string.lua:20
-> error("value is nil", 5) : api_string.lua:66
Run Code Online (Sandbox Code Playgroud)
这将返回“nice”错误,但是,想象一下您也可以handle_when_x_string更直接地调用(抛开糟糕的 API 设计不谈),
another_api_fn(x) : user_file.lua:44
-> another_api_fn : api.lua:11
-> handle_when_x_string : api_string.lua:20
-> error("value is nil", 5) : api_string.lua:66
Run Code Online (Sandbox Code Playgroud)
现在我们的“流行水平”不正确。也许在这个例子中,它会简单地弹出到顶部并停止尝试,但“不正确级别”的原则至少仍然令人不舒服,它甚至可能会“弹出”用户导致错误的位置。
我可以看到一些解决方案:
api_function& another_api_fn) 以下的任何内容包装在 pcall 中,捕获任何错误并使用已知的“良好”级别值重新冒泡。return nil, error或某种类似的模式,然后检查api_function并按要求执行操作。我的问题是:
首先,您需要区分由于错误的 API 调用而导致的错误以及代码中的实际错误。
如果调用的目的error是告诉 API 用户他们传递了错误的参数,那么您应该验证每个 API 函数中的参数,以便错误级别是可知的,并且库的其余部分知道它正在使用有效的参数论据。如果您最终得到了验证函数的复杂层次结构,它们可以采用函数名称和错误级别的参数。这是一个非常人为的示例,说明如何使用错误级别:
local function lessThan100(x, funcName, errorLevel)
if x >=100 then
error(funcName .. ' needs a number less than 100', errorLevel)
end
end
local function numLessThan100(x, funcName, errorLevel)
if type(x) ~= 'number' then
error(funcName .. ' needs a number', errorLevel)
end
lessThan100(x, funcName, errorLevel + 1)
end
-- API function
local function printNum(x)
numLessThan100(x, 'printNum', 3)
print(x)
end
Run Code Online (Sandbox Code Playgroud)
如果error调用代表代码中的错误,则不要使用级别,因为您无法知道是什么触发了错误。