diff options
author | Nicolas Noble <nnoble@blizzard.com> | 2013-07-24 14:23:25 -0700 |
---|---|---|
committer | Nicolas Noble <nnoble@blizzard.com> | 2013-07-24 14:23:25 -0700 |
commit | 712b4bed9973c60b5c139f98e51ed804ce8a628d (patch) | |
tree | 5a634d54a49d71e1dc6091092d8a8f763403446b | |
parent | e37ef65aaa42e790a741c15dbae9b83e9c04cd3a (diff) |
Better exception handling support for Lua.
-rw-r--r-- | includes/LuaTask.h | 6 | ||||
-rw-r--r-- | src/BLua.cc | 21 | ||||
-rw-r--r-- | src/LuaTask.cc | 17 |
3 files changed, 38 insertions, 6 deletions
diff --git a/includes/LuaTask.h b/includes/LuaTask.h index 50226cd..1f7a0b5 100644 --- a/includes/LuaTask.h +++ b/includes/LuaTask.h @@ -12,10 +12,11 @@ class LuaMainTask; class LuaExecCell { public: LuaExecCell(); - virtual ~LuaExecCell() { } + virtual ~LuaExecCell() { if (m_exception) delete m_exception; } void detach() { m_detached = true; } void exec(LuaMainTask * mainTask); - bool gotError() { return m_gotError; } + bool gotError() { return m_gotError || m_exception; } + void throwError() throw (GeneralException); protected: virtual void run(Lua &) = 0; void setError() { m_gotError = true; } @@ -23,6 +24,7 @@ class LuaExecCell { Events::Async m_event; bool m_detached = false; bool m_gotError = false; + GeneralException * m_exception = NULL; friend class LuaTask; LuaExecCell(const LuaExecCell &) = delete; diff --git a/src/BLua.cc b/src/BLua.cc index 21a7452..29b68c2 100644 --- a/src/BLua.cc +++ b/src/BLua.cc @@ -474,12 +474,19 @@ Balau::String Balau::Lua::tostring(int i) { struct LoadF { Balau::IO<Balau::Handle> f; char buff[BUFFERSIZE]; + Balau::GeneralException * exception = NULL; }; const char * Balau::LuaStatics::getF(lua_State * L, void * ud, size_t * size) { LoadF * lf = (LoadF *)ud; - *size = lf->f->read(lf->buff, BUFFERSIZE); + try { + *size = lf->f->read(lf->buff, BUFFERSIZE); + } + catch (GeneralException e) { + lf->exception = new GeneralException(e); + AssertHelper("LuaJIT is lame."); + } return (*size > 0) ? lf->buff : NULL; } @@ -522,9 +529,15 @@ void Balau::Lua::load(IO<Handle> h, bool docall) throw (GeneralException) { status = lua_load(L, LuaStatics::getF, &lf, name.to_charp()); if (status) { - pushLuaContext(); - showerror(); - throw LuaException(String("Error loading lua chunk from Handle `") + h->getName() + "'"); + if (lf.exception) { + GeneralException copy(*lf.exception); + delete lf.exception; + throw copy; + } else { + pushLuaContext(); + showerror(); + throw LuaException(String("Error loading lua chunk from Handle `") + h->getName() + "'"); + } } if (docall) diff --git a/src/LuaTask.cc b/src/LuaTask.cc index 12d4435..fc92cdf 100644 --- a/src/LuaTask.cc +++ b/src/LuaTask.cc @@ -60,6 +60,9 @@ void Balau::LuaTask::Do() { try { m_cell->run(L); } + catch (GeneralException e) { + m_cell->m_exception = new GeneralException(e); + } catch (...) { m_cell->setError(); } @@ -77,6 +80,20 @@ void Balau::LuaExecCell::exec(LuaMainTask * mainTask) { Task::operationYield(&m_event); } +void Balau::LuaExecCell::throwError() throw (GeneralException) { + if (!gotError()) + return; + + if (m_exception) { + GeneralException copy(*m_exception); + delete m_exception; + m_exception = NULL; + throw copy; + } else { + throw GeneralException("Unknown error"); + } +} + void Balau::LuaExecString::run(Lua & L) { L.load(m_str); } |