0

I have a C++ program that I have bound to Lua using luabind. I am currently testing the error handling methods that lua and luabind have to offer in order to help with debugging the lua scripts down the road. The objective is to have luabind or lua throw an exception when syntax errors and programming mistakes arise so that I can debug and correct them.

Right now, the problem is that the script below just stops executing without any error messages or exceptions being thrown, so in a larger program I would have no idea where the problem would be or even if there was a problem in the first place.

Here are the relevant snippets:

Lua: (start.lua)

--complete file shown, this is meant to test the error handling of the C++ program
print("This is valid")
print(1234)
bad_function()
a = "meow"
b = 7
c = a + b

C++:

Engine *callbackEngine;
int theCallback(lua_State *L) //This is so I can use my own function as an
                              //exception handler, pcall_log()
{
    return callbackEngine->pcall_log(L);
}

void Engine::Run()
{
    luabind::set_pcall_callback(&theCallback); //my own callback function, 
                                               //redirects to
                                               //pcall_log() below
try {
    luaL_dofile(L, "scripts/start.lua");
}
catch(luabind::error &sError) { //This never gets executed, noted by breakpoints
    theCallback(L);
}
//etc...code not shown

int Engine::pcall_log(lua_State *L)
{
    lua_Debug d;
    lua_getstack( L,1,&d);
    lua_getinfo( L, "Sln", &d);
    lua_pop(L, 1);
    stringstream ss;
    ss.clear();
    ss.str("");
    ss << d.short_src;
    ss << ": ";
    ss << d.currentline;
    ss << ": ";
    if ( d.name != 0)
    {
        ss << d.namewhat;
        ss << " ";
        ss << d.name;
        ss << ") ";
    }
    ss << lua_tostring(L, -1);
    logger->log(ss.str().c_str(),ELL_ERROR);
    return 1;
}

Here is the output when run:

This is valid
1234

The script stops running instead of throwing an exception like I anticipated. Is there a way to control when lua throws an exception or another way to handle errors? I have the logging function setup to produce debugging information, but breakpoints reveal that the catch statement above is not getting executed.

Thank you!

Brian
  • 145
  • 1
  • 3
  • 13

2 Answers2

2

luaL_dofile() is not part of Luabind so I wouldn't expect any Luabind exceptions from it. The handler you set is used/passed when Luabind itself calls something from Lua (using pcall()). luaL_dofile() is part of the basic Lua code (the L suffix marks it as a library wrapper to simplify calls) and plain C so you'll have to do your own error handling (never used exceptions with Lua/Luabind to be honest) after the call.

Untested, but the following code should do what you expected your code to do:

if(!luaL_doFile(L, "scripts/start.lua"))
    theCallback(L);
Mario
  • 35,726
  • 5
  • 62
  • 78
2

If you want to load a Lua script through Luabind, then you can't use luaL_dofile or other regular Lua functions to do it. You have to use Luabind functions. So that would look something like this:

namespace lb = luabind;
int luaError = luaL_loadfile(pLuaState, "scripts/start.lua");
//Check for errors

lb::object compiledScript(lb::from_stack(pLuaState, -1));
lb::call_function<void>(compiledScript); //Call the script.

lua_pop(pLuaState, 1); //Remove the script from the stack. It's stored in our luabind::object
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Well, you can `lua_pcall` a chunk but you can't expect a C++ exception. Won't the Luabind 'runtime' simply put the `what()` exception message on the Lua stack and call `lua_error`? This is what I expected from the documentation and what seems to happen with a simple test. (Using `luabind::call_function` does let the exception through however.) – Luc Danton Aug 02 '11 at 09:48
  • @Brian: Luabind does not completely invalidate the Lua API. It simply wraps part of it. However, if you do need to get the string Luabind style, you can use `luabind::from_stack` to convert a stack entry into a `luabind::object`. – Nicol Bolas Aug 02 '11 at 10:14
  • Thank you, this works! When the script encounters an error, it now gets routed to my callback function as desired. It also crashes the host program after an error. Still looking into this... – Brian Aug 02 '11 at 10:20
  • It appears that trying to call a registered function with the wrong argument type will crash the program. I need a way to catch this and gracefully handle the incorrect type without segfaulting the program... – Brian Aug 02 '11 at 10:41