diff --git a/docs/changelog.txt b/docs/changelog.txt index 5e65b4909..0559b2dde 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -46,6 +46,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Internals ## Lua +- ``new()``: improved error handling so that certain errors that were previously uncatchable (creating objects with members with unknown vtables) are now catchable with ``pcall()`` ## Removed diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index 59bd96732..1ea4865bd 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -685,7 +685,8 @@ static int meta_new(lua_State *state) type_identity *id = get_object_identity(state, 1, "df.new()", true); - void *ptr; + void *ptr = nullptr; + std::string err_context; // Support arrays of primitive types if (argc == 2) @@ -703,11 +704,22 @@ static int meta_new(lua_State *state) } else { - ptr = id->allocate(); + try { + ptr = id->allocate(); + } + catch (std::exception &e) { + if (e.what()) { + err_context = e.what(); + } + } } if (!ptr) - luaL_error(state, "Cannot allocate %s", id->getFullName().c_str()); + luaL_error(state, "Cannot allocate %s%s%s", + id->getFullName().c_str(), + err_context.empty() ? "" : ": ", + err_context.c_str() + ); if (lua_isuserdata(state, 1)) {