Error object cannot be nil
Lua will change a nil as error object to a string message, so that it never reports an error with nil as the error object.
This commit is contained in:
4
ldebug.c
4
ldebug.c
@@ -844,7 +844,9 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
|||||||
va_start(argp, fmt);
|
va_start(argp, fmt);
|
||||||
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
if (msg != NULL && isLua(ci)) { /* Lua function? (and no error) */
|
if (msg == NULL) /* no memory to format message? */
|
||||||
|
luaD_throw(L, LUA_ERRMEM);
|
||||||
|
else if (isLua(ci)) { /* Lua function? */
|
||||||
/* add source:line information */
|
/* add source:line information */
|
||||||
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
luaG_addinfo(L, msg, ci_func(ci)->p->source, getcurrentline(ci));
|
||||||
setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */
|
setobjs2s(L, L->top.p - 2, L->top.p - 1); /* remove 'msg' */
|
||||||
|
|||||||
10
ldo.c
10
ldo.c
@@ -112,12 +112,16 @@ void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
lua_assert(errorstatus(errcode)); /* real error */
|
lua_assert(errorstatus(errcode)); /* must be a real error */
|
||||||
setobjs2s(L, oldtop, L->top.p - 1); /* error message on current top */
|
if (!ttisnil(s2v(L->top.p - 1))) { /* error object is not nil? */
|
||||||
|
setobjs2s(L, oldtop, L->top.p - 1); /* move it to 'oldtop' */
|
||||||
|
}
|
||||||
|
else /* change it to a proper message */
|
||||||
|
setsvalue2s(L, oldtop, luaS_newliteral(L, "<error object is nil>"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
L->top.p = oldtop + 1;
|
L->top.p = oldtop + 1; /* top goes back to old top plus error object */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -290,7 +290,9 @@ an @def{error object}
|
|||||||
is propagated with information about the error.
|
is propagated with information about the error.
|
||||||
Lua itself only generates errors whose error object is a string,
|
Lua itself only generates errors whose error object is a string,
|
||||||
but programs can generate errors with
|
but programs can generate errors with
|
||||||
any value as the error object.
|
any value as the error object,
|
||||||
|
except @nil.
|
||||||
|
(Lua will change a @nil as error object to a string message.)
|
||||||
It is up to the Lua program or its host to handle such error objects.
|
It is up to the Lua program or its host to handle such error objects.
|
||||||
For historical reasons,
|
For historical reasons,
|
||||||
an error object is often called an @def{error message},
|
an error object is often called an @def{error message},
|
||||||
@@ -8082,6 +8084,8 @@ multiple assignment:
|
|||||||
The default for @id{a2} is @id{a1}.
|
The default for @id{a2} is @id{a1}.
|
||||||
The destination range can overlap with the source range.
|
The destination range can overlap with the source range.
|
||||||
The number of elements to be moved must fit in a Lua integer.
|
The number of elements to be moved must fit in a Lua integer.
|
||||||
|
If @id{f} is larger than @id{e},
|
||||||
|
nothing is moved.
|
||||||
|
|
||||||
Returns the destination table @id{a2}.
|
Returns the destination table @id{a2}.
|
||||||
|
|
||||||
@@ -9402,6 +9406,11 @@ declare a local variable with the same name in the loop body.
|
|||||||
A chain of @id{__call} metamethods can have at most 15 objects.
|
A chain of @id{__call} metamethods can have at most 15 objects.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@item{
|
||||||
|
In an error, a @nil as the error object is replaced by a
|
||||||
|
string message.
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ end
|
|||||||
assert(doit("error('hi', 0)") == 'hi')
|
assert(doit("error('hi', 0)") == 'hi')
|
||||||
|
|
||||||
-- test nil error message
|
-- test nil error message
|
||||||
assert(doit("error()") == nil)
|
assert(doit("error()") == "<error object is nil>")
|
||||||
|
|
||||||
|
|
||||||
-- test common errors/errors that crashed in the past
|
-- test common errors/errors that crashed in the past
|
||||||
@@ -614,7 +614,7 @@ do
|
|||||||
assert(not res and msg == t)
|
assert(not res and msg == t)
|
||||||
|
|
||||||
res, msg = pcall(function () error(nil) end)
|
res, msg = pcall(function () error(nil) end)
|
||||||
assert(not res and msg == nil)
|
assert(not res and msg == "<error object is nil>")
|
||||||
|
|
||||||
local function f() error{msg='x'} end
|
local function f() error{msg='x'} end
|
||||||
res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end)
|
res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end)
|
||||||
@@ -634,7 +634,7 @@ do
|
|||||||
assert(not res and msg == t)
|
assert(not res and msg == t)
|
||||||
|
|
||||||
res, msg = pcall(assert, nil, nil)
|
res, msg = pcall(assert, nil, nil)
|
||||||
assert(not res and msg == nil)
|
assert(not res and type(msg) == "string")
|
||||||
|
|
||||||
-- 'assert' without arguments
|
-- 'assert' without arguments
|
||||||
res, msg = pcall(assert)
|
res, msg = pcall(assert)
|
||||||
|
|||||||
Reference in New Issue
Block a user