我正在使用Lua来解析用某种语言编写的脚本(让我们称之为L)并创建可以由例如运行的Lua代码。 LuaJIT。但是为了简化用户的调试,我想将Lua / LuaJIT给出的运行时错误映射到L文件中的正确行。我这样做是通过xpcalling创建的Lua代码,翻译错误消息和堆栈跟踪,然后使用此消息调用错误。不幸的是,这给了我两个堆栈跟踪,一个是由我创建的,另一个是追溯到调用错误的函数。有可能摆脱这种堆栈跟踪,还是有更好的方法来做到这一点?
local status, err = xpcall(loadedCode, debug.traceback)
if not status then
error(createANewErrorMessageWithPrettyTraceback(err),0)
end
输出:
luajit: ./my/file.name:5: Some error message
stack traceback:
my pretty traceback
stack traceback:
[C]: in function 'error'
./my/file/calling/error.lua:44: in function <./my/file/calling/error.lua:26>
./my-main:16: in main chunk
[C]: at 0x00404180
我知道,例如Moonscript做了类似的事情,但据我所知,他们只是将新的错误信息写入stderr然后继续正常,而不是停止我想做的程序。
有可能做到这一点,然后调用没有参数的错误,这将使程序失败(实际上我认为它的错误失败),但这感觉就像一个非常丑陋的解决方案,所以我宁愿保持愚蠢的第二个痕迹比那样
PS:我假设标题实际上不起作用(因为错误只需要两个参数),所以我实际上问的是如何能够实现这样的事情。 (是否有其他功能可能会做类似的事情,或者我应该在哪里找出如何自己编写该功能。)
编辑:是否可以编辑错误用于获取其回溯的函数,就像使用debug.traceback一样?
答案 0 :(得分:3)
我想做类似的事情(仅直接来自Lua)我最终覆盖debug.traceback
函数本身来改变堆栈跟踪以满足我的需要。我的代码如下;看看这个方法是否适合你:
local dtraceback = debug.traceback
debug.traceback = function (...)
if select('#', ...) >= 1 then
local err, lvl = ...
if err and type(err) ~= 'thread' then
local trace = dtraceback(err, (lvl or 2)+1)
if genv.print == iobase.print then -- no remote redirect
return trace
else
genv.print(trace) -- report the error remotely
return -- don't report locally to avoid double reporting
end
end
end
-- direct call to debug.traceback: return the original.
-- debug.traceback(nil, level) doesn't work in Lua 5.1
-- (http://lua-users.org/lists/lua-l/2011-06/msg00574.html), so
-- simply remove first frame from the stack trace
return (dtraceback(...):gsub("(stack traceback:\n)[^\n]*\n", "%1"))
end
答案 1 :(得分:2)
您只需显示所需的修改回溯即可退出。
local function errh(err)
print(createANewErrorMessageWithPrettyTraceback(debug.traceback(err, 2)))
os.exit(-1) -- error code
end
local status, result = xpcall(loadedCode, errh)
-- The script will never reach this point if there is an error.
print(result)