2013-12-12 7 views
5

私はいくつかの言語で書かれたスクリプトを解析するためにLuaを使用しています(Lと呼んでください)。ルアジット。しかし、ユーザのデバッグを簡単にするために、Lua/LuaJITで与えられた実行時エラーをLファイルの正しい行にマップしたいと考えています。私は、作成したLuaコードをxpcallingして、エラーメッセージとスタックトレースを翻訳してから、このメッセージでエラーを呼び出します。残念ながら、これは私に2つのスタックトレースを与えます。一つは私が作成し、もう一つはエラーを呼び出した関数にトレースします。このスタックトレースを取り除くことは可能ですか、これを行うにはより良い方法がありますか?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に書き込んだり、やりたいことであるプログラムを停止するのではなく、通常通り続行します。
これを実行して引数を指定せずにエラーを呼び出すと、プログラムが失敗する可能性があります(実際にはエラーが発生したと思います)。しかし、これはかなり醜い解決策のように感じます。それよりも2番目の痕跡。
PS:実際にはタイトルが尋ねるものは動作しません(エラーには2つの引数しかないので)。だから私が実際に求めていることは、このようなことがどのように達成できるかです。 (おそらく似たようなことをしている他の関数や、自分でその関数を書く方法を理解する必要がある場所はありますか?)
編集:エラーがトレースバックを取得するために使用している関数をそのまま編集することは可能でしょうか? 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 
関連する問題