From 3324bb013cdd5e835bd8374d5c31f037948f89f0 Mon Sep 17 00:00:00 2001 From: rxi Date: Sun, 2 Mar 2014 17:13:18 +0000 Subject: [PATCH] Added error handling to lume.hotswap() Changed lume.hotswap() to return an error and restore the global environment if an error occurs when requiring the new package --- README.md | 14 ++++++++------ lume.lua | 28 ++++++++++++++++++---------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index bcdc7ad..17fb766 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ A collection of functions for Lua, geared towards game development. ## Installation -The [lume.lua](lume.lua?raw=1) file should be dropped into an existing project and -required by it: +The [lume.lua](lume.lua?raw=1) file should be dropped into an existing project +and required by it: ```lua lume = require "lume" @@ -205,12 +205,14 @@ lume.dostring("print('Hello!')") -- Prints "Hello!" ``` ### lume.hotswap(modname) -Reloads an already loaded module in place; `modname` should be the same string -used when loading the module with require(). This function can be used to -immediatly see the effects of code changes without having to restart the -program. +Reloads an already loaded module in place, allowing you to immediatly see the +effects of code changes without having to restart the program. `modname` should +be the same string used when loading the module with require(). In the case of +an error the global environment is restored and `nil` plus an error message is +returned. ```lua lume.hotswap("lume") -- Reloads the lume module +assert(lume.hotswap("inexistant_module")) -- Raises an error ``` ### lume.rgba(color) diff --git a/lume.lua b/lume.lua index 274f7dd..1ccd563 100644 --- a/lume.lua +++ b/lume.lua @@ -229,6 +229,7 @@ end function lume.hotswap(modname) + local oldglobal = lume.clone(_G) local updated = {} local function update(old, new) if updated[old] then return end @@ -239,18 +240,25 @@ function lume.hotswap(modname) if type(v) == "table" then update(old[k], v) else old[k] = v end end end - local oldglobal = lume.clone(_G) local oldmod = require(modname) - package.loaded[modname] = nil - local newmod = require(modname) - package.loaded[modname] = oldmod - if type(oldmod) == "table" then update(oldmod, newmod) end - for k, v in pairs(oldglobal) do - if v ~= _G[k] and type(v) == "table" then - update(v, _G[k]) - _G[k] = v - end + local err = nil + local function onerror(e) + for k, v in pairs(_G) do _G[k] = oldglobal[k] end + err = lume.trim(e) end + xpcall(function() + package.loaded[modname] = nil + local newmod = require(modname) + if type(oldmod) == "table" then update(oldmod, newmod) end + for k, v in pairs(oldglobal) do + if v ~= _G[k] and type(v) == "table" then + update(v, _G[k]) + _G[k] = v + end + end + end, onerror) + package.loaded[modname] = oldmod + if err then return nil, err end return oldmod end