@@ -51,8 +51,10 @@ import { EventBuilder } from './EventBuilder';
51
51
import { ExceptionlessClient } from './ExceptionlessClient' ;
52
52
import { Utils } from './Utils' ;
53
53
54
- const EXIT :string = 'exit' ;
55
- const UNCAUGHT_EXCEPTION :string = 'uncaughtException' ;
54
+ const EXIT : string = 'exit' ;
55
+ const UNCAUGHT_EXCEPTION : string = 'uncaughtException' ;
56
+ const SIGINT : string = 'SIGINT' ;
57
+ const SIGINT_CODE : number = 2 ;
56
58
57
59
var defaults = Configuration . defaults ;
58
60
defaults . environmentInfoCollector = new NodeEnvironmentInfoCollector ( ) ;
@@ -61,34 +63,51 @@ defaults.exitController = new NodeExitController();
61
63
defaults . requestInfoCollector = new NodeRequestInfoCollector ( ) ;
62
64
defaults . submissionClient = new NodeSubmissionClient ( ) ;
63
65
64
- function getListenerCount ( emitter , event ) : number {
66
+ function getListenerCount ( emitter , event : string ) : number {
65
67
if ( emitter . listenerCount ) {
66
68
return emitter . listenerCount ( event ) ;
67
69
}
68
-
69
70
return require ( "events" ) . listenerCount ( emitter , event ) ;
70
71
}
71
72
72
- process . on ( UNCAUGHT_EXCEPTION , function ( error :Error ) {
73
- ExceptionlessClient . default . submitUnhandledException ( error , UNCAUGHT_EXCEPTION ) ;
73
+ /*
74
+ * Adding a event handler for 'uncaughtException' modifies the default
75
+ * Node behavior, so it won't exit or log to the console. Instead,
76
+ * we hijack the event emitter and forward the exception to the callback.
77
+ */
78
+ function onUncaughtException ( callback : ( error : Error ) => void ) {
79
+ var originalEmit = process . emit ;
80
+
81
+ process . emit = function ( type : string , error : Error ) {
82
+ if ( type === UNCAUGHT_EXCEPTION ) {
83
+ callback ( error ) ;
84
+ }
74
85
75
- /*
76
- * Default Node behavior: If this is the only uncaught-listener, we still exit.
77
- * Discussion: https://nodejs.org/api/process.html#process_event_uncaughtexception
78
- */
79
- var uncaughtListenerCount = getListenerCount ( process , UNCAUGHT_EXCEPTION ) ;
80
- if ( uncaughtListenerCount <= 1 ) {
81
- process . exit ( 1 ) ;
86
+ return originalEmit . apply ( this , arguments ) ;
82
87
}
88
+ }
89
+
90
+ onUncaughtException ( function ( error : Error ) {
91
+ ExceptionlessClient . default . submitUnhandledException ( error , UNCAUGHT_EXCEPTION ) ;
83
92
} ) ;
84
93
85
- process . on ( EXIT , function ( code :number ) {
94
+ /*
95
+ * We cannot hijack SIGINT, so if there are no other handlers,
96
+ * we just reproduce default Node.js behavior by exiting.
97
+ */
98
+ process . on ( SIGINT , function ( ) {
99
+ if ( getListenerCount ( process , SIGINT ) <= 1 ) {
100
+ process . exit ( 128 + SIGINT_CODE ) ;
101
+ }
102
+ } )
103
+
104
+ process . on ( EXIT , function ( code : number ) {
86
105
/**
87
106
* exit codes: https://nodejs.org/api/process.html#process_event_exit
88
107
* From now on, only synchronous code may run. As soon as this method
89
108
* ends, the application inevitably will exit.
90
109
*/
91
- function getExitCodeReason ( code :number ) : string {
110
+ function getExitCodeReason ( code : number ) : string {
92
111
if ( code === 1 ) {
93
112
return 'Uncaught Fatal Exception' ;
94
113
}
@@ -129,10 +148,6 @@ process.on(EXIT, function (code:number) {
129
148
return 'Invalid Debug Argument' ;
130
149
}
131
150
132
- if ( code > 128 ) {
133
- return 'Signal Exits' ;
134
- }
135
-
136
151
return null ;
137
152
}
138
153
0 commit comments