Skip to content

Commit b585858

Browse files
mhdawsondanielleadams
authored andcommitted
node-api: handle pending exception in cb wrapper
fixes: nodejs/node-addon-api#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 <[email protected]> PR-URL: #39476 Fixes: nodejs/node-addon-api#1025 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]>
1 parent b1b6f20 commit b585858

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

src/js_native_api_v8.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,16 @@ class CallbackWrapperBase : public CallbackWrapper {
306306
napi_env env = _bundle->env;
307307
napi_callback cb = _bundle->cb;
308308

309-
napi_value result;
309+
napi_value result = nullptr;
310+
bool exceptionOccurred = false;
310311
env->CallIntoModule([&](napi_env env) {
311312
result = cb(env, cbinfo_wrapper);
313+
}, [&](napi_env env, v8::Local<v8::Value> value) {
314+
exceptionOccurred = true;
315+
env->isolate->ThrowException(value);
312316
});
313317

314-
if (result != nullptr) {
318+
if (!exceptionOccurred && (result != nullptr)) {
315319
this->SetReturnValue(result);
316320
}
317321
}

test/js-native-api/test_function/test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,11 @@ assert.deepStrictEqual(test_function.TestCreateFunctionParameters(), {
4242
cbIsNull: 'Invalid argument',
4343
resultIsNull: 'Invalid argument'
4444
});
45+
46+
assert.throws(
47+
() => test_function.TestBadReturnExceptionPending(),
48+
{
49+
code: 'throwing exception',
50+
name: 'Error'
51+
}
52+
);

test/js-native-api/test_function/test_function.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,19 @@ static napi_value MakeTrackedFunction(napi_env env, napi_callback_info info) {
138138
return result;
139139
}
140140

141+
static napi_value TestBadReturnExceptionPending(napi_env env, napi_callback_info info) {
142+
napi_throw_error(env, "throwing exception", "throwing exception");
143+
144+
// addons should only ever return a valid napi_value even if an
145+
// exception occurs, but we have seen that the C++ wrapper
146+
// with exceptions enabled sometimes returns an invalid value
147+
// when an exception is thrown. Test that we ignore the return
148+
// value then an exeption is pending. We use 0xFFFFFFFF as a value
149+
// that should never be a valid napi_value and node seems to
150+
// crash if it is not ignored indicating that it is indeed invalid.
151+
return (napi_value)(0xFFFFFFFFF);
152+
}
153+
141154
EXTERN_C_START
142155
napi_value Init(napi_env env, napi_value exports) {
143156
napi_value fn1;
@@ -164,6 +177,12 @@ napi_value Init(napi_env env, napi_value exports) {
164177
env, "TestCreateFunctionParameters", NAPI_AUTO_LENGTH,
165178
TestCreateFunctionParameters, NULL, &fn5));
166179

180+
napi_value fn6;
181+
NODE_API_CALL(env,
182+
napi_create_function(
183+
env, "TestBadReturnExceptionPending", NAPI_AUTO_LENGTH,
184+
TestBadReturnExceptionPending, NULL, &fn6));
185+
167186
NODE_API_CALL(env, napi_set_named_property(env, exports, "TestCall", fn1));
168187
NODE_API_CALL(env, napi_set_named_property(env, exports, "TestName", fn2));
169188
NODE_API_CALL(env,
@@ -175,6 +194,10 @@ napi_value Init(napi_env env, napi_value exports) {
175194
napi_set_named_property(
176195
env, exports, "TestCreateFunctionParameters", fn5));
177196

197+
NODE_API_CALL(env,
198+
napi_set_named_property(
199+
env, exports, "TestBadReturnExceptionPending", fn6));
200+
178201
return exports;
179202
}
180203
EXTERN_C_END

0 commit comments

Comments
 (0)