From 4c2add3832097ffee44e438c81200fb1c332985c Mon Sep 17 00:00:00 2001 From: UnlegitDqrk Date: Sun, 1 Mar 2026 19:36:19 +0100 Subject: [PATCH] Fixed issue: #94 --- .../src/main/java/org/luaj/vm2/LuaClosure.java | 18 ++++++++++-------- core/src/main/java/org/luaj/vm2/LuaError.java | 4 ++++ .../test/java/org/luaj/vm2/FragmentsTest.java | 11 +++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/luaj/vm2/LuaClosure.java b/core/src/main/java/org/luaj/vm2/LuaClosure.java index b9bb652e..d862a2b5 100644 --- a/core/src/main/java/org/luaj/vm2/LuaClosure.java +++ b/core/src/main/java/org/luaj/vm2/LuaClosure.java @@ -591,19 +591,19 @@ public class LuaClosure extends LuaFunction { * Run the error hook if there is one * @param msg the message to use in error hook processing. * */ - String errorHook(String msg, int level) { - if (globals == null ) return msg; + LuaValue errorHook(LuaValue msgobj, String msg, int level) { + if (globals == null ) return LuaValue.valueOf(msg); final LuaThread r = globals.running; if (r.errorfunc == null) - return globals.debuglib != null? + return LuaValue.valueOf(globals.debuglib != null? msg + "\n" + globals.debuglib.traceback(level): - msg; + msg); final LuaValue e = r.errorfunc; r.errorfunc = null; try { - return e.call( LuaValue.valueOf(msg) ).tojstring(); + return e.call(msgobj != null ? msgobj : LuaValue.NIL); } catch ( Throwable t ) { - return "error in error handling"; + return LuaValue.valueOf("error in error handling"); } finally { r.errorfunc = e; } @@ -628,7 +628,9 @@ public class LuaClosure extends LuaFunction { } } le.fileline = file + ":" + line; - le.traceback = errorHook(le.getMessage(), le.level); + LuaValue error = errorHook(le.getMessageObject(), le.getMessage(), le.level); + le.setMessageObject(error); + le.traceback = error != null ? error.tojstring() : null; } private UpValue findupval(LuaValue[] stack, short idx, UpValue[] openups) { @@ -656,4 +658,4 @@ public class LuaClosure extends LuaFunction { } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/luaj/vm2/LuaError.java b/core/src/main/java/org/luaj/vm2/LuaError.java index 37a8df8d..c6708017 100644 --- a/core/src/main/java/org/luaj/vm2/LuaError.java +++ b/core/src/main/java/org/luaj/vm2/LuaError.java @@ -75,6 +75,10 @@ public class LuaError extends RuntimeException { String m = getMessage(); return m != null ? LuaValue.valueOf(m): null; } + + public void setMessageObject(LuaValue messageObject) { + this.object = messageObject; + } /** Construct LuaError when a program exception occurs. *

diff --git a/jse/src/test/java/org/luaj/vm2/FragmentsTest.java b/jse/src/test/java/org/luaj/vm2/FragmentsTest.java index 33846915..bf343ace 100644 --- a/jse/src/test/java/org/luaj/vm2/FragmentsTest.java +++ b/jse/src/test/java/org/luaj/vm2/FragmentsTest.java @@ -591,6 +591,17 @@ public class FragmentsTest extends TestSuite { runFragment(LuaValue.varargsOf(LuaValue.valueOf("boolean"), LuaValue.TRUE), "a,b = pcall(error, true); return type(b), b\n"); } + public void testXpcallHandlerResultReplacesStringError() { + runFragment(LuaValue.varargsOf(LuaValue.valueOf("table"), LuaValue.valueOf(1)), + "local ok, err = xpcall(function() error('oh no') end, function(e) return { marker = 1, original = e } end)\n" + + "return type(err), err.marker\n"); + } + public void testXpcallHandlerGetsOriginalErrorObject() { + runFragment(LuaValue.varargsOf(LuaValue.valueOf("table"), LuaValue.valueOf(1)), + "local source = { marker = 1 }\n" + + "local ok, err = xpcall(function() error(source) end, function(e) return e end)\n" + + "return type(err), err.marker\n"); + } public void testBalancedMatchOnEmptyString() { runFragment(LuaValue.NIL, "return (\"\"):match(\"%b''\")\n"); }