@@ -524,9 +524,51 @@ static void OnFatalError(const char* location, const char* message) {
524
524
exit (1 );
525
525
}
526
526
527
+ static int uncaught_exception_counter = 0 ;
528
+
527
529
void FatalException (TryCatch &try_catch) {
528
- ReportException (&try_catch);
529
- exit (1 );
530
+ HandleScope scope;
531
+
532
+ // Check if uncaught_exception_counter indicates a recursion
533
+ if (uncaught_exception_counter > 0 ) {
534
+ ReportException (&try_catch);
535
+ exit (1 );
536
+ }
537
+
538
+ Local<Value> listeners_v = process->Get (String::NewSymbol (" listeners" ));
539
+ assert (listeners_v->IsFunction ());
540
+
541
+ Local<Function> listeners = Local<Function>::Cast (listeners_v);
542
+
543
+ Local<String> uncaught_exception = String::NewSymbol (" uncaughtException" );
544
+
545
+ Local<Value> argv[1 ] = { uncaught_exception };
546
+ Local<Value> ret = listeners->Call (process, 1 , argv);
547
+
548
+ assert (ret->IsArray ());
549
+
550
+ Local<Array> listener_array = Local<Array>::Cast (ret);
551
+
552
+ uint32_t length = listener_array->Length ();
553
+ // Report and exit if process has no "uncaughtException" listener
554
+ if (length == 0 ) {
555
+ ReportException (&try_catch);
556
+ exit (1 );
557
+ }
558
+
559
+ // Otherwise fire the process "uncaughtException" event
560
+ Local<Value> emit_v = process->Get (String::NewSymbol (" emit" ));
561
+ assert (emit_v->IsFunction ());
562
+
563
+ Local<Function> emit = Local<Function>::Cast (emit_v);
564
+
565
+ Local<Value> error = try_catch.Exception ();
566
+ Local<Value> event_argv[2 ] = { uncaught_exception, error };
567
+
568
+ uncaught_exception_counter++;
569
+ emit->Call (process, 2 , event_argv);
570
+ // Decrement so we know if the next exception is a recursion or not
571
+ uncaught_exception_counter--;
530
572
}
531
573
532
574
static ev_async eio_watcher;
0 commit comments