Lua:如何调用无堆栈跟踪的错误?

我使用Lua解析用某种语言编写的脚本(称为L),并创建可通过LuaJIT等运行的Lua代码。但为了简化用户的调试,我希望将Lua / LuaJIT提供的运行时错误映射到L文件中的正确行。我通过xpcall创建了Lua代码,将错误消息和堆栈跟踪转换后,使用此消息调用error。不幸的是,这给了我两个堆栈跟踪,一个由我创建,另一个跟踪回调用error的函数。是否可能消除此堆栈跟踪,或是否有更好的方法来实现此目的?

点赞
用户1442917
用户1442917

我想做类似的事情(只是直接从 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
    -- 直接调用 debug.traceback:返回原始的。
    -- Lua 5.1 中 debug.traceback(nil, level) 不起作用(参考:http://lua-users.org/lists/lua-l/2011-06/msg00574.html),
    -- 因此只需从堆栈跟踪中删除第一个框架即可。
    return (dtraceback(...):gsub("(stack traceback:\n)[^\n]*\n", "%1"))
  end
2013-12-13 21:54:43
用户828255
用户828255

你可以简单地显示你想要的修改后的 traceback 然后退出。

local function errh(err)
    print(createANewErrorMessageWithPrettyTraceback(debug.traceback(err, 2)))
    os.exit(-1) -- 错误代码
end

local status, result = xpcall(loadedCode, errh)
-- 如果有错误,脚本永远不会执行到这一点。
print(result)
2013-12-15 01:19:32