From 47b4773786d8dd96878e05ea7084d922b3da42bb Mon Sep 17 00:00:00 2001 From: lethosor Date: Fri, 4 Aug 2023 17:14:08 -0400 Subject: [PATCH] df.new(): catch errors thrown by allocate() This can include DFHack::Error::VTableMissing exceptions if the vtable of a member field is unknown. Fixes #3627 --- docs/changelog.txt | 1 + library/LuaWrapper.cpp | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) 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)) {