From fe3082679c8eaa3b6d8b380f4c215701e3d6dc67 Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Thu, 9 Jul 2020 11:00:41 -0700 Subject: [PATCH] src: wrap finalizer callback --- napi-inl.h | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/napi-inl.h b/napi-inl.h index 99ed3e3d3..80dd9b933 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -82,6 +82,24 @@ inline napi_value WrapCallback(Callable callback) { #endif // NAPI_CPP_EXCEPTIONS } +// For use in JS to C++ void callback wrappers to catch any Napi::Error +// exceptions and rethrow them as JavaScript exceptions before returning from the +// callback. +template +inline void WrapVoidCallback(Callable callback) { +#ifdef NAPI_CPP_EXCEPTIONS + try { + callback(); + } catch (const Error& e) { + e.ThrowAsJavaScriptException(); + } +#else // NAPI_CPP_EXCEPTIONS + // When C++ exceptions are disabled, errors are immediately thrown as JS + // exceptions, so there is no need to catch and rethrow them here. + callback(); +#endif // NAPI_CPP_EXCEPTIONS +} + template struct CallbackData { static inline @@ -120,17 +138,21 @@ struct CallbackData { template struct FinalizeData { static inline - void Wrapper(napi_env env, void* data, void* finalizeHint) { - FinalizeData* finalizeData = static_cast(finalizeHint); - finalizeData->callback(Env(env), static_cast(data)); - delete finalizeData; + void Wrapper(napi_env env, void* data, void* finalizeHint) noexcept { + WrapVoidCallback([&] { + FinalizeData* finalizeData = static_cast(finalizeHint); + finalizeData->callback(Env(env), static_cast(data)); + delete finalizeData; + }); } static inline - void WrapperWithHint(napi_env env, void* data, void* finalizeHint) { - FinalizeData* finalizeData = static_cast(finalizeHint); - finalizeData->callback(Env(env), static_cast(data), finalizeData->hint); - delete finalizeData; + void WrapperWithHint(napi_env env, void* data, void* finalizeHint) noexcept { + WrapVoidCallback([&] { + FinalizeData* finalizeData = static_cast(finalizeHint); + finalizeData->callback(Env(env), static_cast(data), finalizeData->hint); + delete finalizeData; + }); } Finalizer callback;