proFromDover
proFromDover

Reputation: 451

Improving Lua error messages

Whenever an error occurs in a Lua script, I'd like it to write the values of all local and global variables to the screen/optionally to a file - in addition to the usual stack trace.

How could I get this to be the default behavior for all errors?

Upvotes: 5

Views: 3530

Answers (4)

Hisham H M
Hisham H M

Reputation: 6798

The StackTracePlus module does what you want, displaying local variables at each level of the stack trace. It doesn't dump the entire globals table, but that is probably overkill.

To install it with LuaRocks, use

luarocks install stacktraceplus

Then in your code, do:

local STP = require "StackTracePlus"
debug.traceback = STP.stacktrace

In Lua 5.1 this will automatically convert all stack traces; for Lua 5.2 code you need to wrap your code with an xpcall as suggested in other answers.

Upvotes: 4

ACyclic
ACyclic

Reputation: 6260

Your error handler may be overwritten. If you're calling Lua from C, to always print the stack you can hook in to the luaG_errormsg function.

In lua, write :

local _HandlingError = 0
function _ErrorHandler ( errobj )
    if( _HandlingError == 0 ) then
        _HandlingError = 1
        local errStr = tostring(errobj) or ""
        if( type(errobj)=='table' ) then
          errStr = "Table: {" .. table.concat(errobj, ',') .. "}"
        end
        print("Error: \"" .. errStr .. "\"")
        --for k,v in pairs(_G) do print("GLOBAL:" , k,v) end
        if( type(errobj)=='thread' ) then
            print(debug.traceback(errobj))
        else
            print(debug.traceback('',2))
        end
        _HandlingError = 0
    end
    return false
end

Then in ldebug.c, add to luaG_errormsg after if(L->errfunc != 0)

else
{
    lua_getfield(L, LUA_GLOBALSINDEX, "_ErrorHandler");
    if (!lua_isfunction(L, -1)) {
        lua_pop(L, 1);
    }
    else {
        lua_pushvalue(L, 1);
        lua_call(L, 2, 1);
        lua_pop(L, 1);
    }
}

Upvotes: 0

daurnimator
daurnimator

Reputation: 4311

A more proper solution would be to use xpcall around your whole code.

local function myerrhandler ( errobj )
    print(debug.traceback())
    for k,v in pairs(_G) do print("GLOBAL:" , k,v) end
    return false
end

xpcall( function ()
--Your code here
end , myerrhandler )

Upvotes: 1

lhf
lhf

Reputation: 72312

If you're using the standard Lua interpreter, replace debug.traceback with your own function. If you're embedding Lua in your program, use your traceback function in lua_pcall.

Upvotes: 3

Related Questions