1
0
Fork 0
mirror of https://github.com/rubyjs/mini_racer synced 2023-03-27 23:21:28 -04:00

Add better function calls error handling

This commit is contained in:
Jb Aviat 2018-03-12 20:11:38 +01:00
parent 62d239d76c
commit 9f358f46dc
2 changed files with 38 additions and 5 deletions

View file

@ -60,6 +60,7 @@ typedef struct {
ContextInfo *context_info;
char *function_name;
int argc;
bool error;
Local<Function> fun;
Local<Value> *argv;
Local<Value> result;
@ -1111,9 +1112,14 @@ nogvl_function_call(void *args) {
Local<Function> fun = call->fun;
Local<v8::Value> res = fun->Call(context, context->Global(), call->argc, call->argv).ToLocalChecked();
call->result = handle_scope.Escape(res);
MaybeLocal<v8::Value> res = fun->Call(context, context->Global(), call->argc, call->argv);
if (res.IsEmpty()) {
// A better error handling should be added, factoring out exception management
// code from nogvl_context_eval
call->error = true;
} else {
call->result = handle_scope.Escape(res.ToLocalChecked());
}
isolate->SetData(IN_GVL, (void*)true);
@ -1148,9 +1154,11 @@ rb_function_call(int argc, VALUE *argv, VALUE self) {
FunctionCall call;
call.error = false;
call.function_name = fname;
call.context_info = context_info;
call.argc = argc - 1;
call.argv = NULL;
VALUE *call_argv = NULL;
if (call.argc > 0) {
// skip first argument which is the function name
@ -1188,8 +1196,13 @@ rb_function_call(int argc, VALUE *argv, VALUE self) {
free(call.argv);
// TODO - check for call errors
res = convert_v8_to_ruby(isolate, call.result);
if (!call.error) {
res = convert_v8_to_ruby(isolate, call.result);
}
}
if (call.error) {
// TODO - better handling of exceptions
rb_raise(rb_eScriptRuntimeError, "Error calling %s", call.function_name);
}
return res;
}

View file

@ -37,6 +37,26 @@ class MiniRacerFunctionTest < Minitest::Test
end
end
def test_non_existing_function
context = MiniRacer::Context.new
context.eval("function f(x) { return 'I need ' + x + ' galettes' }")
# f is defined, let's call g
assert_raises(MiniRacer::RuntimeError) do
context.function_call('g')
end
end
def test_throwing_function
context = MiniRacer::Context.new
context.eval("function f(x) { throw new Error() }")
# f is defined, let's call g
assert_raises(MiniRacer::RuntimeError) do
context.function_call('f', 1)
end
end
def test_args_types
context = MiniRacer::Context.new
context.eval("function f(x, y) { return 'I need ' + x + ' ' + y }")