Sign in to follow this  
jackiechan

Catching string and errors in lua

Recommended Posts

I'm working on a little lua wrapper for my class project. I'm down to getting error handling portion of the wrapper. Is there a way to catch the error strings and reroute any output (ie print "this is a string";) into something i can catch?

Share this post


Link to post
Share on other sites
When an error occurs lua (5.0) calls the function _ALERT with a string parameter. Simply overwrite that with your own output function and do whatever you want with the error.

I can't help with rerouting the output though. You could do it quite the same way, overwriting the provided function with your own implementation, but there's probably an easier way.

Share this post


Link to post
Share on other sites
Of all the things you'll do with lua, this is one of the most awkward and annoying. Because lua is a C based API, it's support for 'Nice' object oriented error handling is a bit limited - at some point the error message needs to be globally visible, either to the lua code or the C++ code.

Digging through some older code I found this - no guarantees that it's correct, but it gives the idea.


std::string gLuaErrorMsg = "";

int luaError( lua_State *L )
{
const char* str = lua_tostring( L, -1 );
lua_pop(L, 1);
gLuaErrorMsg = str;
return 0;
}

LuaInterpreter::LuaInterpreter()
{
L_ = lua_open();
lua_register( L_, "_ALERT", luaError );

//... code continues
}

void LuaInterpreter::doFile(const char* filename)
{
int errcode = lua_dofile(L_, filename);
if(errcode != 0)
{
throw std::runtime_error(gLuaErrorMsg);
}
}


Share this post


Link to post
Share on other sites
The error handling can be done in various ways.

In protected environoment the internal error handling will use setjmp/longjmp to return to a "safe point". There the error will safely be returned to you (and you can use a simple if(...) throw sentence). (Example: when you use lua_pcall).

If you are in a non-protected environment: This is often the case if you don't use lua_pcall (but may call other functions such as lua_tostring in which errors may occur), lua will call lua_error->luaD_throw->[panic function]. After the panic function is done it will call exit(...) (terminates the entire program). Probably not what you want in a wrapper.

You can fix this by registering your own panic function:
lua_atpanic(L, func_panic);

The panic function could be something like:
int ScriptState::func_panic(State *L)
{
adt::string str;

str << pop_string(L);
lua_getglobal(L, "ERROR");
throw ScriptException(str, (int)lua_tonumber(L, -1));

return 0;
}

You will bypass the exit(..) call and everything will be cleaned up internallly by the lua_error function. It may not be wise to throw the exception anywere else due to memory leak risks etc.







[Edited by - alich on November 25, 2004 11:35:10 AM]

Share this post


Link to post
Share on other sites
Thanks for the help guys. I've got a few work arounds at the moment as I familiarize myself better with lua. Right now I'm working on catching syntax errors in the script. It keeps throwing me tables instead of strings for me to handle. If anyone knows the name of the table and the fields in that table, it would be fabulous.

Share this post


Link to post
Share on other sites
"throwing you tables"?

can you be more precise, what function do you use? lua_load uses protected environment (via luaD_protectedparser). So any syntax error will be returned to the client.
When the error code != 0 you can use lua_tostring(L, -1) and do what you want.

Lua does not throw tables when errors occur. It pushes a string on the stack (idx == -1).

I assume you use lua5.0.2.





Share this post


Link to post
Share on other sites
Here's the code snippet im working on:

int top = -1;
int type = -1;
std::string msg;

top = lua_gettop( L );

if( top > 0 )
{
type = lua_type( L, top );
}

msg = "Message Not Available";
if( type == LUA_TSTRING )
{
msg = lua_tostring( L, top );
}

I have a check if the type is a string, then I can get the string info and handle the error. I tested the code with some simple errors that I placed in the script and I keep getting LUA_TTABLE instead of LUA_TSTRING that is expected. So that's why I was wondering if I could get the error info from the table. Unless I'm doing something wrong and I'm not realizing it.

Share this post


Link to post
Share on other sites
assume you are calling with lua_pcall:
this will work:

if(lua_pcall(...))
{
if(lua_isstring(L, -1))
{
const char *err = lua_tostring(L, -1);
printf(err);
}
}

if you can't get a string return from lua, please be more specific and tell me exactly what luafunction you are working with, not just your error function (won't help me much)...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this