diff --git a/src/NoYield.lua b/src/NoYield.lua index bb2a9ed..f116a4f 100644 --- a/src/NoYield.lua +++ b/src/NoYield.lua @@ -10,8 +10,15 @@ local function resultHandler(co: thread, ok: boolean, ...) if not ok then - local message = (...) - error(debug.traceback(co, message), 2) + local err = (...) + if typeof(err) == "string" then + error(debug.traceback(co, err), 2) + else + -- If the error is not of type string, just assume it has some + -- meaningful information and rethrow it with a `tostring` so that + -- top-level error handlers can process it + error(tostring(err), 2) + end end if coroutine.status(co) ~= "dead" then diff --git a/src/NoYield.spec.lua b/src/NoYield.spec.lua index 58b48d6..4880a62 100644 --- a/src/NoYield.spec.lua +++ b/src/NoYield.spec.lua @@ -53,4 +53,30 @@ return function() expect(err:find("foo")).to.be.ok() expect(err:find("NoYield.spec")).to.be.ok() end) + + it("should handle non-string error messages", function() + local count = 0 + + local function makeErrorObject() + return setmetatable({ + message = "errored with an error object", + stack = debug.traceback(), + }, { + __tostring = function(self) + return self.message .. "\n" .. self.stack + end, + }) + end + + local function test() + count = count + 1 + error(makeErrorObject()) + end + + local ok, err = pcall(NoYield, test) + + expect(ok).to.equal(false) + expect(err:find("errored with an error object")).to.be.ok() + expect(err:find("NoYield.spec")).to.be.ok() + end) end