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
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
这将返回“不错”的错误,但是,想象一下您也可以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
现在我们的“流行级别”是不正确的。也许在这个例子中,它会简单地弹出到顶部并停止尝试,但“错误级别”的原则至少仍然令人不舒服,它甚至可能会“弹出”用户导致错误的地方。
我可以看到一些解决方案:
- 不要设置级别,只是假设用户足够聪明,可以解决问题。
- 在 pcall 中包装 api 入口点 (
api_function
&another_api_fn
) 以下的任何内容,捕获任何错误并使用已知的“良好”级别值重新冒泡。 - 永远不要在较低的 api 函数中出错,总是
return nil, error
或类似的模式,然后检查它api_function
并根据需要采取行动。
我的问题是:
- 返回错误的级别是否有问题?只是“是的,随便”一个数字似乎很糟糕,希望它是好的。
- 如果这是一个问题,什么时候设置级别是一个好习惯(可能超过 0 会禁用位置报告)
- 如果有的话,哪些解决方案是最佳实践?我应该怎么做才能写出更好的可维护代码?包装在 pcall 中似乎是最简单的,因为在测试时您仍然可以依赖“正常错误”,并且您的功能有些简单,但不知何故,在我的脑海中感觉像是一种反模式。