Skip to content

Commit 2ca12c8

Browse files
mhdawsontargos
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 78de83c commit 2ca12c8

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
@@ -153,6 +153,19 @@ static napi_value MakeTrackedFunction(napi_env env, napi_callback_info info) {
153153
return result;
154154
}
155155

156+
static napi_value TestBadReturnExceptionPending(napi_env env, napi_callback_info info) {
157+
napi_throw_error(env, "throwing exception", "throwing exception");
158+
159+
// addons should only ever return a valid napi_value even if an
160+
// exception occurs, but we have seen that the C++ wrapper
161+
// with exceptions enabled sometimes returns an invalid value
162+
// when an exception is thrown. Test that we ignore the return
163+
// value then an exeption is pending. We use 0xFFFFFFFF as a value
164+
// that should never be a valid napi_value and node seems to
165+
// crash if it is not ignored indicating that it is indeed invalid.
166+
return (napi_value)(0xFFFFFFFFF);
167+
}
168+
156169
EXTERN_C_START
157170
napi_value Init(napi_env env, napi_value exports) {
158171
napi_value fn1;
@@ -183,6 +196,12 @@ napi_value Init(napi_env env, napi_value exports) {
183196
NULL,
184197
&fn5));
185198

199+
napi_value fn6;
200+
NAPI_CALL(env,
201+
napi_create_function(
202+
env, "TestBadReturnExceptionPending", NAPI_AUTO_LENGTH,
203+
TestBadReturnExceptionPending, NULL, &fn6));
204+
186205
NAPI_CALL(env, napi_set_named_property(env, exports, "TestCall", fn1));
187206
NAPI_CALL(env, napi_set_named_property(env, exports, "TestName", fn2));
188207
NAPI_CALL(env, napi_set_named_property(env, exports, "TestNameShort", fn3));
@@ -196,6 +215,10 @@ napi_value Init(napi_env env, napi_value exports) {
196215
"TestCreateFunctionParameters",
197216
fn5));
198217

218+
NAPI_CALL(env,
219+
napi_set_named_property(
220+
env, exports, "TestBadReturnExceptionPending", fn6));
221+
199222
return exports;
200223
}
201224
EXTERN_C_END

0 commit comments

Comments
 (0)