Skip to content

Commit e4f4a94

Browse files
committed
Fix: Output uncaught exception to console
- Replaced uncaught handler by shim - Added support for SIGINT
1 parent 2d77694 commit e4f4a94

File tree

3 files changed

+51
-27
lines changed

3 files changed

+51
-27
lines changed

dist/exceptionless.node.js

+16-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/exceptionless.node.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/exceptionless.node.ts

+34-19
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ import { EventBuilder } from './EventBuilder';
5151
import { ExceptionlessClient } from './ExceptionlessClient';
5252
import { Utils } from './Utils';
5353

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;
5658

5759
var defaults = Configuration.defaults;
5860
defaults.environmentInfoCollector = new NodeEnvironmentInfoCollector();
@@ -61,34 +63,51 @@ defaults.exitController = new NodeExitController();
6163
defaults.requestInfoCollector = new NodeRequestInfoCollector();
6264
defaults.submissionClient = new NodeSubmissionClient();
6365

64-
function getListenerCount(emitter, event):number {
66+
function getListenerCount(emitter, event:string): number {
6567
if (emitter.listenerCount) {
6668
return emitter.listenerCount(event);
6769
}
68-
6970
return require("events").listenerCount(emitter, event);
7071
}
7172

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+
}
7485

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);
8287
}
88+
}
89+
90+
onUncaughtException(function(error: Error) {
91+
ExceptionlessClient.default.submitUnhandledException(error, UNCAUGHT_EXCEPTION);
8392
});
8493

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) {
86105
/**
87106
* exit codes: https://nodejs.org/api/process.html#process_event_exit
88107
* From now on, only synchronous code may run. As soon as this method
89108
* ends, the application inevitably will exit.
90109
*/
91-
function getExitCodeReason(code:number): string {
110+
function getExitCodeReason(code: number): string {
92111
if (code === 1) {
93112
return 'Uncaught Fatal Exception';
94113
}
@@ -129,10 +148,6 @@ process.on(EXIT, function (code:number) {
129148
return 'Invalid Debug Argument';
130149
}
131150

132-
if (code > 128) {
133-
return 'Signal Exits';
134-
}
135-
136151
return null;
137152
}
138153

0 commit comments

Comments
 (0)