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:
parent
dd18795997
commit
79b2c9a371
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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'
|
||||
}
|
||||
);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user