API: nvim_eval(): return non-generic VimL errors

Use the same pattern as nvim_call_function (_call_function).
This commit is contained in:
Justin M. Keyes 2018-05-09 03:23:18 +02:00
parent 32b0470b03
commit 2326a4ac3a
2 changed files with 24 additions and 4 deletions

View File

@ -268,11 +268,30 @@ theend:
Object nvim_eval(String expr, Error *err) Object nvim_eval(String expr, Error *err)
FUNC_API_SINCE(1) FUNC_API_SINCE(1)
{ {
static int recursive = 0; // recursion depth
Object rv = OBJECT_INIT; Object rv = OBJECT_INIT;
// `msg_list` controls the collection of abort-causing non-exception errors,
// which would otherwise be ignored. This pattern is from do_cmdline().
struct msglist **saved_msg_list = msg_list;
struct msglist *private_msg_list;
msg_list = &private_msg_list;
private_msg_list = NULL;
// Initialize `force_abort` and `suppress_errthrow` at the top level.
if (!recursive) {
force_abort = false;
suppress_errthrow = false;
current_exception = NULL;
// `did_emsg` is set by emsg(), which cancels execution.
did_emsg = false;
}
recursive++;
try_start(); try_start();
typval_T rettv; typval_T rettv;
if (eval0((char_u *)expr.data, &rettv, NULL, true) == FAIL) { if (eval0((char_u *)expr.data, &rettv, NULL, true) == FAIL) {
// This generic error should be overwritten by try_end() since #8371.
api_set_error(err, kErrorTypeException, "Failed to evaluate expression"); api_set_error(err, kErrorTypeException, "Failed to evaluate expression");
} }
@ -281,6 +300,8 @@ Object nvim_eval(String expr, Error *err)
} }
tv_clear(&rettv); tv_clear(&rettv);
msg_list = saved_msg_list; // Restore the exception context.
recursive--;
return rv; return rv;
} }

View File

@ -146,10 +146,9 @@ describe('api', function()
eq(2, request("vim_eval", "1+1")) eq(2, request("vim_eval", "1+1"))
end) end)
it("VimL error: fails (generic error), does NOT update v:errmsg", function() it("VimL error: returns error details, does NOT update v:errmsg", function()
local status, rv = pcall(nvim, "eval", "bogus expression") expect_err('E121: Undefined variable: bogus', request,
eq(false, status) -- nvim_eval() failed. 'nvim_eval', 'bogus expression')
ok(nil ~= string.find(rv, "Failed to evaluate expression"))
eq('', eval('v:errmsg')) -- v:errmsg was not updated. eq('', eval('v:errmsg')) -- v:errmsg was not updated.
end) end)
end) end)