From 64f651533187c11ad28a46d9a7e733de3d940173 Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Fri, 14 Apr 2023 15:57:06 -0700 Subject: [PATCH] src: handle failure during error wrap of primitive When we wrap a primitive value into an object in order to throw it as an error, we call `napi_define_properties()` which may return `napi_pending_exception` if the environment is shutting down. Handle this case when `NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS` is given by checking whether we're in an environment shutdown scenario and ignore the failure of `napi_define_properties()`, since the error will not reach JS anyway. Signed-off-by: Gabriel Schulhof PR-URL: https://github.com/nodejs/node-addon-api/pull/1310 Reviewed-By: Chengzhong Wu Reviewed-By: Michael Dawson --- napi-inl.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/napi-inl.h b/napi-inl.h index c6ef0fbb0..a9d1fec3f 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -2937,6 +2937,22 @@ inline Error::Error(napi_env env, napi_value value) nullptr}; status = napi_define_properties(env, wrappedErrorObj, 1, &wrapObjFlag); +#ifdef NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS + if (status == napi_pending_exception) { + // Test if the pending exception was reported because the environment is + // shutting down. We assume that a status of napi_pending_exception + // coupled with the absence of an actual pending exception means that + // the environment is shutting down. If so, we replace the + // napi_pending_exception status with napi_ok. + bool is_exception_pending = false; + status = napi_is_exception_pending(env, &is_exception_pending); + if (status == napi_ok && !is_exception_pending) { + status = napi_ok; + } else { + status = napi_pending_exception; + } + } +#endif // NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS NAPI_FATAL_IF_FAILED(status, "Error::Error", "napi_define_properties"); // Create a reference on the newly wrapped object