diff --git a/src/controllers/plugins/LuaUtilities.cpp b/src/controllers/plugins/LuaUtilities.cpp index 64af18c01..9d86b1430 100644 --- a/src/controllers/plugins/LuaUtilities.cpp +++ b/src/controllers/plugins/LuaUtilities.cpp @@ -266,5 +266,29 @@ QString toString(lua_State *L, StackIdx idx) const auto *ptr = luaL_tolstring(L, idx, &len); return QString::fromUtf8(ptr, int(len)); } + +void PeekResult::throwAsLuaError(lua_State *L) +{ + // Note that this uses lua buffers to ensure deallocation of the error string + luaL_Buffer buf; + luaL_buffinit(L, &buf); + bool first = true; + for (const auto &s : this->errorReason) + { + if (!first) + { + luaL_addchar(&buf, '\n'); + } + first = false; + luaL_addstring(&buf, s.toStdString().c_str()); + } + // Remove our copy + this->errorReason.clear(); + + luaL_pushresult(&buf); + lua_error(L); // This call never returns + assert(false && "unreachable"); +} + } // namespace chatterino::lua #endif diff --git a/src/controllers/plugins/LuaUtilities.hpp b/src/controllers/plugins/LuaUtilities.hpp index 5443a751f..82a1df64a 100644 --- a/src/controllers/plugins/LuaUtilities.hpp +++ b/src/controllers/plugins/LuaUtilities.hpp @@ -69,6 +69,22 @@ StackIdx push(lua_State *L, const bool &b); StackIdx push(lua_State *L, const int &b); StackIdx push(lua_State *L, const api::CompletionEvent &ev); +struct PeekResult { + bool ok = true; + std::vector errorReason = {}; + + operator bool() const + { + return this->ok; + } + + /** + * Combines errorReason into a single string and then calls luaL_error. + * As luaL_error never returns this function does not either. + */ + [[noreturn]] void throwAsLuaError(lua_State *L); +}; + // returns OK? bool peek(lua_State *L, int *out, StackIdx idx = -1); bool peek(lua_State *L, bool *out, StackIdx idx = -1);