2013-12-12 55 views
5

我正在使用Lua來分析用某種語言編寫的腳本(我們稱之爲L)並創建可以由其運行的Lua代碼。 LuaJIT。但爲了簡化用戶調試,我想將Lua/LuaJIT給出的運行時錯誤映射到L文件中的正確行。我通過xpcalling創建的Lua代碼,翻譯錯誤消息和stacktrace然後用這個消息調用錯誤來做到這一點。不幸的是,這給了我兩個堆棧跟蹤,一個由我創建,一個跟蹤到稱爲錯誤的函數。是否有可能擺脫這個堆棧跟蹤,還是有更好的方法來做到這一點?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

爲什麼不直接打印回溯而不是調用錯誤的? –

+0

因爲我想讓程序在發生錯誤時失敗,而不是僅僅告訴用戶發生了什麼事情。但正如Ryan Stein指出的那樣,我可以調用os.exit。 – MartinValen

回答

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) 
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 
相關問題