0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-24 20:29:23 +01:00

node-api: handle pending exception in cb wrapper

fixes: https://github.com/nodejs/node-addon-api/issues/1025

The functionreference test from the node-api tests
was reporting a failed v8 check when Node.js was compiled
as debug. The failure was because an exception was
pending but the C++ wrappers were returning
a return value that was invalid.

Signed-off-by: Michael Dawson <mdawson@devrus.com>

PR-URL: https://github.com/nodejs/node/pull/39476
Fixes: https://github.com/nodejs/node-addon-api/issues/1025
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
Michael Dawson 2021-07-20 21:41:58 -04:00
parent dd18795997
commit 79b2c9a371
3 changed files with 37 additions and 2 deletions

View File

@ -306,12 +306,16 @@ class CallbackWrapperBase : public CallbackWrapper {
napi_env env = _bundle->env;
napi_callback cb = _bundle->cb;
napi_value result;
napi_value result = nullptr;
bool exceptionOccurred = false;
env->CallIntoModule([&](napi_env env) {
result = cb(env, cbinfo_wrapper);
}, [&](napi_env env, v8::Local<v8::Value> value) {
exceptionOccurred = true;
env->isolate->ThrowException(value);
});
if (result != nullptr) {
if (!exceptionOccurred && (result != nullptr)) {
this->SetReturnValue(result);
}
}

View File

@ -42,3 +42,11 @@ assert.deepStrictEqual(test_function.TestCreateFunctionParameters(), {
cbIsNull: 'Invalid argument',
resultIsNull: 'Invalid argument'
});
assert.throws(
() => test_function.TestBadReturnExceptionPending(),
{
code: 'throwing exception',
name: 'Error'
}
);

View File

@ -138,6 +138,19 @@ static napi_value MakeTrackedFunction(napi_env env, napi_callback_info info) {
return result;
}
static napi_value TestBadReturnExceptionPending(napi_env env, napi_callback_info info) {
napi_throw_error(env, "throwing exception", "throwing exception");
// addons should only ever return a valid napi_value even if an
// exception occurs, but we have seen that the C++ wrapper
// with exceptions enabled sometimes returns an invalid value
// when an exception is thrown. Test that we ignore the return
// value then an exeption is pending. We use 0xFFFFFFFF as a value
// that should never be a valid napi_value and node seems to
// crash if it is not ignored indicating that it is indeed invalid.
return (napi_value)(0xFFFFFFFFF);
}
EXTERN_C_START
napi_value Init(napi_env env, napi_value exports) {
napi_value fn1;
@ -164,6 +177,12 @@ napi_value Init(napi_env env, napi_value exports) {
env, "TestCreateFunctionParameters", NAPI_AUTO_LENGTH,
TestCreateFunctionParameters, NULL, &fn5));
napi_value fn6;
NODE_API_CALL(env,
napi_create_function(
env, "TestBadReturnExceptionPending", NAPI_AUTO_LENGTH,
TestBadReturnExceptionPending, NULL, &fn6));
NODE_API_CALL(env, napi_set_named_property(env, exports, "TestCall", fn1));
NODE_API_CALL(env, napi_set_named_property(env, exports, "TestName", fn2));
NODE_API_CALL(env,
@ -175,6 +194,10 @@ napi_value Init(napi_env env, napi_value exports) {
napi_set_named_property(
env, exports, "TestCreateFunctionParameters", fn5));
NODE_API_CALL(env,
napi_set_named_property(
env, exports, "TestBadReturnExceptionPending", fn6));
return exports;
}
EXTERN_C_END