1
- #ifndef SRC_NAPI_INL_H_
1
+ #ifndef SRC_NAPI_INL_H_
2
2
#define SRC_NAPI_INL_H_
3
3
4
4
// //////////////////////////////////////////////////////////////////////////////
@@ -38,19 +38,15 @@ inline void RegisterModule(napi_env env,
38
38
Napi::Object (env, module ));
39
39
}
40
40
catch (const Error& e) {
41
- if (!Napi::Env (env).IsExceptionPending ()) {
42
- e.ThrowAsJavaScriptException ();
43
- }
41
+ e.ThrowAsJavaScriptException ();
44
42
}
45
43
}
46
44
47
45
// For use in JS to C++ callback wrappers to catch any Napi::Error exceptions
48
46
// and rethrow them as JavaScript exceptions before returning from the callback.
49
47
#define NAPI_RETHROW_JS_ERROR (env ) \
50
48
catch (const Error& e) { \
51
- if (!Napi::Env (env).IsExceptionPending ()) { \
52
- e.ThrowAsJavaScriptException (); \
53
- } \
49
+ e.ThrowAsJavaScriptException (); \
54
50
return nullptr ; \
55
51
}
56
52
@@ -1215,14 +1211,6 @@ inline Value Function::Call(napi_value recv, const std::vector<napi_value>& args
1215
1211
return Value (_env, result);
1216
1212
}
1217
1213
1218
- inline Value Function::MakeCallback (const std::initializer_list<napi_value>& args) const {
1219
- return MakeCallback (Env ().Undefined (), args);
1220
- }
1221
-
1222
- inline Value Function::MakeCallback (const std::vector<napi_value>& args) const {
1223
- return MakeCallback (Env ().Undefined (), args);
1224
- }
1225
-
1226
1214
inline Value Function::MakeCallback (
1227
1215
napi_value recv, const std::initializer_list<napi_value>& args) const {
1228
1216
napi_value result;
@@ -1888,16 +1876,6 @@ inline Napi::Value FunctionReference::Call(
1888
1876
return scope.Escape (Value ().Call (recv, args));
1889
1877
}
1890
1878
1891
- inline Napi::Value FunctionReference::MakeCallback (const std::initializer_list<napi_value>& args) const {
1892
- EscapableHandleScope scope (_env);
1893
- return scope.Escape (Value ().MakeCallback (args));
1894
- }
1895
-
1896
- inline Napi::Value FunctionReference::MakeCallback (const std::vector<napi_value>& args) const {
1897
- EscapableHandleScope scope (_env);
1898
- return scope.Escape (Value ().MakeCallback (args));
1899
- }
1900
-
1901
1879
inline Napi::Value FunctionReference::MakeCallback (
1902
1880
napi_value recv, const std::initializer_list<napi_value>& args) const {
1903
1881
EscapableHandleScope scope (_env);
@@ -2481,7 +2459,7 @@ inline napi_value ObjectWrap<T>::InstanceVoidMethodCallbackWrapper(
2481
2459
InstanceVoidMethodCallbackData* callbackData =
2482
2460
reinterpret_cast <InstanceVoidMethodCallbackData*>(callbackInfo.Data ());
2483
2461
callbackInfo.SetData (callbackData->data );
2484
- T* instance = Unwrap (callbackInfo.This ());
2462
+ T* instance = Unwrap (callbackInfo.This (). As <Object>() );
2485
2463
auto cb = callbackData->callback ;
2486
2464
(instance->*cb)(callbackInfo);
2487
2465
return nullptr ;
@@ -2498,7 +2476,7 @@ inline napi_value ObjectWrap<T>::InstanceMethodCallbackWrapper(
2498
2476
InstanceMethodCallbackData* callbackData =
2499
2477
reinterpret_cast <InstanceMethodCallbackData*>(callbackInfo.Data ());
2500
2478
callbackInfo.SetData (callbackData->data );
2501
- T* instance = Unwrap (callbackInfo.This ());
2479
+ T* instance = Unwrap (callbackInfo.This (). As <Object>() );
2502
2480
auto cb = callbackData->callback ;
2503
2481
return (instance->*cb)(callbackInfo);
2504
2482
}
@@ -2514,7 +2492,7 @@ inline napi_value ObjectWrap<T>::InstanceGetterCallbackWrapper(
2514
2492
InstanceAccessorCallbackData* callbackData =
2515
2493
reinterpret_cast <InstanceAccessorCallbackData*>(callbackInfo.Data ());
2516
2494
callbackInfo.SetData (callbackData->data );
2517
- T* instance = Unwrap (callbackInfo.This ());
2495
+ T* instance = Unwrap (callbackInfo.This (). As <Object>() );
2518
2496
auto cb = callbackData->getterCallback ;
2519
2497
return (instance->*cb)(callbackInfo);
2520
2498
}
@@ -2530,7 +2508,7 @@ inline napi_value ObjectWrap<T>::InstanceSetterCallbackWrapper(
2530
2508
InstanceAccessorCallbackData* callbackData =
2531
2509
reinterpret_cast <InstanceAccessorCallbackData*>(callbackInfo.Data ());
2532
2510
callbackInfo.SetData (callbackData->data );
2533
- T* instance = Unwrap (callbackInfo.This ());
2511
+ T* instance = Unwrap (callbackInfo.This (). As <Object>() );
2534
2512
auto cb = callbackData->setterCallback ;
2535
2513
(instance->*cb)(callbackInfo, callbackInfo[0 ]);
2536
2514
return nullptr ;
@@ -2606,9 +2584,13 @@ inline Value EscapableHandleScope::Escape(napi_value escapee) {
2606
2584
// //////////////////////////////////////////////////////////////////////////////
2607
2585
2608
2586
inline AsyncWorker::AsyncWorker (const Function& callback)
2609
- : _callback(Napi::Persistent(callback)),
2610
- _persistent(Napi::Persistent(Object::New(callback.Env()))),
2611
- _env(callback.Env()) {
2587
+ : AsyncWorker(Object::New(callback.Env()), callback) {
2588
+ }
2589
+
2590
+ inline AsyncWorker::AsyncWorker (const Object& receiver, const Function& callback)
2591
+ : _env(callback.Env()),
2592
+ _receiver(Napi::Persistent(receiver)),
2593
+ _callback(Napi::Persistent(callback)) {
2612
2594
napi_status status = napi_create_async_work (
2613
2595
_env, OnExecute, OnWorkComplete, this , &_work);
2614
2596
if (status != napi_ok) throw Error::New (_env);
@@ -2626,7 +2608,8 @@ inline AsyncWorker::AsyncWorker(AsyncWorker&& other) {
2626
2608
other._env = nullptr ;
2627
2609
_work = other._work ;
2628
2610
other._work = nullptr ;
2629
- _persistent = std::move (other._persistent );
2611
+ _receiver = std::move (other._receiver );
2612
+ _callback = std::move (other._callback );
2630
2613
_error = std::move (other._error );
2631
2614
}
2632
2615
@@ -2635,7 +2618,8 @@ inline AsyncWorker& AsyncWorker::operator =(AsyncWorker&& other) {
2635
2618
other._env = nullptr ;
2636
2619
_work = other._work ;
2637
2620
other._work = nullptr ;
2638
- _persistent = std::move (other._persistent );
2621
+ _receiver = std::move (other._receiver );
2622
+ _callback = std::move (other._callback );
2639
2623
_error = std::move (other._error );
2640
2624
return *this ;
2641
2625
}
@@ -2658,48 +2642,59 @@ inline void AsyncWorker::Cancel() {
2658
2642
if (status != napi_ok) throw Error::New (_env);
2659
2643
}
2660
2644
2661
- inline void AsyncWorker::WorkComplete () {
2662
- HandleScope scope (_env);
2663
- if (_error.IsEmpty ()) {
2664
- OnOK ();
2665
- }
2666
- else {
2667
- OnError (_error);
2668
- }
2645
+ inline ObjectReference& AsyncWorker::Receiver () {
2646
+ return _receiver;
2669
2647
}
2670
2648
2671
- inline ObjectReference & AsyncWorker::Persistent () {
2672
- return _persistent ;
2649
+ inline FunctionReference & AsyncWorker::Callback () {
2650
+ return _callback ;
2673
2651
}
2674
2652
2675
2653
inline void AsyncWorker::OnOK () {
2676
- _callback.MakeCallback (Env (). Undefined (), std::vector<napi_value>() );
2654
+ _callback.MakeCallback (_receiver. Value (), {} );
2677
2655
}
2678
2656
2679
- inline void AsyncWorker::OnError (Error e) {
2680
- HandleScope scope (Env ());
2681
- _callback.MakeCallback (Env ().Undefined (), std::vector<napi_value>({ e.Value () }));
2657
+ inline void AsyncWorker::OnError (Error& e) {
2658
+ _callback.MakeCallback (_receiver.Value (), { e.Value () });
2682
2659
}
2683
2660
2684
- inline void AsyncWorker::SetError (Error error) {
2661
+ inline void AsyncWorker::SetError (const std::string& error) {
2685
2662
_error = error;
2686
2663
}
2687
2664
2688
2665
inline void AsyncWorker::OnExecute (napi_env env, void * this_pointer) {
2689
2666
AsyncWorker* self = static_cast <AsyncWorker*>(this_pointer);
2690
2667
try {
2691
2668
self->Execute ();
2692
- }
2693
- catch (const Error& e) {
2694
- self->SetError (e);
2669
+ } catch (const std::exception& e) {
2670
+ self->SetError (e.what ());
2695
2671
}
2696
2672
}
2697
2673
2698
2674
inline void AsyncWorker::OnWorkComplete (
2699
2675
napi_env env, napi_status status, void * this_pointer) {
2700
2676
AsyncWorker* self = static_cast <AsyncWorker*>(this_pointer);
2701
2677
if (status != napi_cancelled) {
2702
- self->WorkComplete ();
2678
+ HandleScope scope (self->_env );
2679
+ try {
2680
+ if (self->_error .size () == 0 ) {
2681
+ self->OnOK ();
2682
+ }
2683
+ else {
2684
+ self->OnError (Error::New (self->_env , self->_error ));
2685
+ }
2686
+ } catch (const Error& e) {
2687
+ // A JS or N-API exception was thrown, and propagated as a C++ exception.
2688
+ // But throwing a JS exception here would have no effect because there
2689
+ // is no JS on the callstack.
2690
+
2691
+ // TODO: Print the exception details and abort, just like Node.js normally
2692
+ // does for unhandled exceptions. But there is no N-API function for that.
2693
+ // For now just assert, so at least the exception message is discoverable
2694
+ // in a debug build.
2695
+ const char * message = e.what ();
2696
+ assert (false );
2697
+ }
2703
2698
}
2704
2699
delete self;
2705
2700
}
0 commit comments