44const char * sqlite_code_string (int code);
55const char * sqlite_authorizer_string (int type);
66#include < vector>
7+ #include < atomic>
78
89// TODO: better way to work around StringConcat?
910#include < napi.h>
11+
12+ // Forward declaration of shutdown flag from node_sqlite3.cc
13+ extern std::atomic<bool > g_env_shutting_down;
14+
1015inline Napi::String StringConcat (Napi::Value str1, Napi::Value str2) {
1116 return Napi::String::New (str1.Env (), str1.As <Napi::String>().Utf8Value () +
1217 str2.As <Napi::String>().Utf8Value () );
@@ -128,8 +133,21 @@ inline bool OtherIsInt(Napi::Number source) {
128133 if ((argc != 0 ) && (passed_argv != NULL )) {\
129134 args.assign (passed_argv, passed_argv + argc);\
130135 }\
131- Napi::Value res = (callback).Call(Napi::Value(context), args); \
132- if (res.IsEmpty()) return __VA_ARGS__;
136+ try {\
137+ Napi::Value res = (callback).Call (Napi::Value (context), args);\
138+ if (res.IsEmpty ()) return __VA_ARGS__;\
139+ } catch (const Napi::Error&) {\
140+ /* During Node.js/Electron shutdown, when using NAPI_CPP_EXCEPTIONS,*/ \
141+ /* we must take care to not throw any exceptions. */ \
142+ /* But when napi_call_function returns napi_cannot_run_js */ \
143+ /* this throws a C++ exception, when NAPI_CPP_EXCEPTIONS is enabled. */ \
144+ if (g_env_shutting_down.load ()) {\
145+ /* We need to silently ignore exceptions during shutdown. */ \
146+ return __VA_ARGS__;\
147+ }\
148+ /* Real rror - re-throw to propagate it */ \
149+ throw ;\
150+ }
133151
134152#define WORK_DEFINITION (name ) \
135153 Napi::Value name (const Napi::CallbackInfo& info); \
@@ -204,4 +222,4 @@ inline bool OtherIsInt(Napi::Number source) {
204222 backup->Process (); \
205223 backup->db->Process ();
206224
207- #endif
225+ #endif
0 commit comments