From b4d5dff8ec4f1c8a44db66d368e95d359b04aea7 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 5 Jun 2019 13:16:25 -0300 Subject: Multiple errors in '__toclose' report the first one When there are multiple errors when closing objects, the error reported by the protected call is the first one, for two reasons: First, other errors may be caused by this one; second, the first error is handled in the original execution context, and therefore has the full traceback. --- lfunc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'lfunc.c') diff --git a/lfunc.c b/lfunc.c index 3e044b65..55114992 100644 --- a/lfunc.c +++ b/lfunc.c @@ -144,13 +144,16 @@ static int callclosemth (lua_State *L, TValue *uv, StkId level, int status) { luaG_runerror(L, "attempt to close non-closable variable '%s'", vname); } } - else { /* there was an error */ + else { /* must close the object in protected mode */ + ptrdiff_t oldtop = savestack(L, level + 1); /* save error message and set stack top to 'level + 1' */ luaD_seterrorobj(L, status, level); if (prepclosingmethod(L, uv, s2v(level))) { /* something to call? */ - int newstatus = luaD_pcall(L, callclose, NULL, savestack(L, level), 0); - if (newstatus != LUA_OK) /* another error when closing? */ + int newstatus = luaD_pcall(L, callclose, NULL, oldtop, 0); + if (newstatus != LUA_OK && status == CLOSEPROTECT) /* first error? */ status = newstatus; /* this will be the new error */ + else /* leave original error (or nil) on top */ + L->top = restorestack(L, oldtop); } /* else no metamethod; ignore this case and keep original error */ } -- cgit v1.2.3-55-g6feb