How to print out errors in the console with the C API for Lua

6k views Asked by At

I have been searching high and low for a way to handle errors with the C API for Lua, and simply print them out in the console. Though, I'm unable to find a single working example. What I would like to do is simply something like:

static int test(lua_State *L)
{
  if(!lua_isstring(L, 1))
     return luaL_error(L, "This is not a valid string");    
}

or

static int test(lua_State *L)
{
    try
    {
        if (!lua_isstring(L, 1))
        {
            throw luaL_error(L, "This is not a valid string");
        }
    }
    catch (int e)
    {
        std::cout << "Error " << e << std::endl;
    }
}

But nothing works as up to this point. What would be the correct way to do the error handling with the LUA C API and show messages in the console?

2

There are 2 answers

0
catwell On BEST ANSWER

The first code example is one of the correct ways to deal with errors in Lua, but you appear to be confused about how it works.

You are writing a C function that implements an interface that will be exposed to Lua. It works like this Lua code:

local function test(s)
    if type(s) ~= "string" then
        error("This is not a valid string")
    end
end

The code that made the error in the first place is not the test function, it is the code that called it with an invalid argument.

When your Lua code calls that function in an invalid way (for instance test(42)), it will raise a Lua error, with the string as the error message. If you call it from a standard Lua interpreter, it will stop the program, print the error message and a stack trace.

If you want to do something else in your Lua code, for instance just print the error message, you can catch the error with pcall which works a bit like try / catch in other languages:

local ok, err_msg = pcall(test, 42)
if not ok then
    print(err_msg)
end

Note that since this error is caused by an invalid argument type, your code can probably be improved by using one of luaL_checkstring / luaL_checklstring, luaL_argcheck or luaL_argerror instead of luaL_error directly.

To learn more about how the C API works, I encourage you to read the dedicated section in the book "Programming in Lua (4th edition)".

0
Andreas Haferburg On

I had the exact same question, and catwell's answer didn't fully answer it for me. What I originally did in my program was simply call

luaL_dofile(L, "example.lua");

Nothing happened when an error occurred.

"If you call it from a standard Lua interpreter..." was a good clue. So I looked at the main in luac.c to see what it does:

if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));

Note that luaL_dofile also expands to lua_pcall. So, if an error is raised while that file is ... done, the only thing that happens is that the error message is pushed onto L's stack. It is your responsibility to do something with it.

So I modified my code accordingly:

#include <stdio.h> // fprintf, stderr
#include <stdlib.h> // exit, EXIT_FAILURE
static void fatal(const char* message) {
  fprintf(stderr,"%s\n", message);
  exit(EXIT_FAILURE);
}
int main(void) {
  ...
  if (luaL_dofile(L, "example.lua") != LUA_OK) {
    fatal(lua_tostring(L,-1));
  }
  ...
}