Skip to content

Commit f005ccb

Browse files
committed
fix: catch C++ exceptions in API bind wrapper
If a C++ exception escapes a bound function, this code now catches it and yields the exception text as an error message via Lua machinery. Optimally the wrapped code should handle exceptions intelligently, but if it doesn't, this is the ultimate safety measure.
1 parent ae253de commit f005ccb

File tree

2 files changed

+17
-12
lines changed

2 files changed

+17
-12
lines changed

engine/core/core_image.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ image_c* image_c::LoaderForFile(IConsole* conHnd, const char* fileName)
9898
}
9999

100100
// Detect first by extension, as decompressing could be expensive.
101-
auto p = std::filesystem::u8path(fileName);
101+
auto p = std::filesystem::path(fileName); // NOTE(LV): This should be u8path later.
102102
if (p.extension() == ".zst") {
103103
auto inner = p.filename();
104104
inner.replace_extension();
@@ -452,7 +452,7 @@ bool gif_c::Save(const char* fileName)
452452

453453
bool dds_c::Load(const char* fileName, std::optional<size_callback_t> sizeCallback)
454454
{
455-
auto p = std::filesystem::u8path(fileName);
455+
auto p = std::filesystem::path(fileName); // NOTE(LV): This should be u8path later.
456456
// Open file
457457
fileInputStream_c in;
458458
if (in.FileOpen(fileName, true))

ui_api.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,15 @@ static int l_##Name(lua_State* L) { \
154154
int (*fun)(lua_State*) = [](lua_State* L) SG_NOINLINE -> int { \
155155
try
156156

157-
#define SG_LUA_CPP_FUN_END() \
158-
catch (ui_expectationFailed_s) { return -1; } \
159-
}; \
160-
int rc = fun(L); \
161-
if (rc < 0) { LuaErrorWrapper(L); } \
157+
#define SG_LUA_CPP_FUN_END() \
158+
catch (ui_expectationFailed_s) { return -1; } \
159+
catch (std::exception& e) { \
160+
lua_pushfstring(L, "C++ exception:\n%s", e.what()); \
161+
return -1; \
162+
} \
163+
}; \
164+
int rc = fun(L); \
165+
if (rc < 0) { LuaErrorWrapper(L); } \
162166
return rc; }
163167

164168
// ===============
@@ -386,14 +390,14 @@ static int l_imgHandleGC(lua_State* L)
386390
return 0;
387391
}
388392

389-
static int l_imgHandleLoad(lua_State* L)
393+
SG_LUA_CPP_FUN_BEGIN(imgHandleLoad)
390394
{
391395
ui_main_c* ui = GetUIPtr(L);
392-
ui->LAssert(L, ui->renderer != NULL, "Renderer is not initialised");
396+
ui->LExpect(L, ui->renderer != NULL, "Renderer is not initialised");
393397
imgHandle_s* imgHandle = GetImgHandle(L, ui, "Load", false);
394398
int n = lua_gettop(L);
395-
ui->LAssert(L, n >= 1, "Usage: imgHandle:Load(fileName[, flag1[, flag2...]])");
396-
ui->LAssert(L, lua_isstring(L, 1), "imgHandle:Load() argument 1: expected string, got %s", luaL_typename(L, 1));
399+
ui->LExpect(L, n >= 1, "Usage: imgHandle:Load(fileName[, flag1[, flag2...]])");
400+
ui->LExpect(L, lua_isstring(L, 1), "imgHandle:Load() argument 1: expected string, got %s", luaL_typename(L, 1));
397401
const char* fileName = lua_tostring(L, 1);
398402
char fullFileName[512];
399403
if (strchr(fileName, ':') || !ui->scriptWorkDir) {
@@ -422,12 +426,13 @@ static int l_imgHandleLoad(lua_State* L)
422426
flags |= TF_NEAREST;
423427
}
424428
else {
425-
ui->LAssert(L, 0, "imgHandle:Load(): unrecognised flag '%s'", flag);
429+
ui->LExpect(L, 0, "imgHandle:Load(): unrecognised flag '%s'", flag);
426430
}
427431
}
428432
imgHandle->hnd = ui->renderer->RegisterShader(fullFileName, flags);
429433
return 0;
430434
}
435+
SG_LUA_CPP_FUN_END()
431436

432437
static int l_imgHandleUnload(lua_State* L)
433438
{

0 commit comments

Comments
 (0)