When catching a global error in Node.js, print the type of error

This commit is contained in:
James Bunton
2018-12-06 22:00:34 +11:00
parent a621d05fa7
commit d803bd12a6
5 changed files with 39 additions and 16 deletions
+9 -5
View File
@@ -98,9 +98,11 @@ describe("GlobalErrors", function() {
errors.pushListener(handler); errors.pushListener(handler);
var addedListener = fakeGlobal.process.on.calls.argsFor(0)[1]; var addedListener = fakeGlobal.process.on.calls.argsFor(0)[1];
addedListener(new Error('bar')); const expectedError = new Error('bar');
addedListener(expectedError);
expect(handler).toHaveBeenCalledWith(new Error('bar')); expect(handler).toHaveBeenCalledWith(expectedError);
expect(expectedError.jasmineMessage).toBe('Uncaught exception: Error: bar');
errors.uninstall(); errors.uninstall();
@@ -127,10 +129,12 @@ describe("GlobalErrors", function() {
errors.pushListener(handler); errors.pushListener(handler);
var addedListener = fakeGlobal.process.on.calls.argsFor(0)[1]; var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
addedListener(new Error('bar')); const expectedError = new Error('bar');
addedListener(expectedError);
expect(handler).toHaveBeenCalledWith(new Error('bar')); expect(handler).toHaveBeenCalledWith(expectedError);
expect(expectedError.jasmineMessage).toBe('Unhandled promise rejection: Error: bar');
errors.uninstall(); errors.uninstall();
+2 -2
View File
@@ -1942,10 +1942,10 @@ describe("Env integration", function() {
reporter.jasmineDone.and.callFake(function() { reporter.jasmineDone.and.callFake(function() {
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('async suite', [ expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('async suite', [
/^(((Uncaught )?Error: suite( thrown)?)|(suite thrown))$/ /^(((Uncaught )?(exception: )?Error: suite( thrown)?)|(suite thrown))$/
]); ]);
expect(reporter.specDone).toHaveFailedExpectationsForRunnable('suite async spec', [ expect(reporter.specDone).toHaveFailedExpectationsForRunnable('suite async spec', [
/^(((Uncaught )?Error: spec( thrown)?)|(spec thrown))$/ /^(((Uncaught )?(exception: )?Error: spec( thrown)?)|(spec thrown))$/
]); ]);
done(); done();
}); });
+6 -3
View File
@@ -1,11 +1,15 @@
getJasmineRequireObj().ExceptionFormatter = function(j$) { getJasmineRequireObj().ExceptionFormatter = function(j$) {
var ignoredProperties = ['name', 'message', 'stack', 'fileName', 'sourceURL', 'line', 'lineNumber', 'column', 'description', 'jasmineMessage'];
function ExceptionFormatter(options) { function ExceptionFormatter(options) {
var jasmineFile = (options && options.jasmineFile) || j$.util.jasmineFile(); var jasmineFile = (options && options.jasmineFile) || j$.util.jasmineFile();
this.message = function(error) { this.message = function(error) {
var message = ''; var message = '';
if (error.name && error.message) { if (error.jasmineMessage) {
message += error.jasmineMessage;
} else if (error.name && error.message) {
message += error.name + ': ' + error.message; message += error.name + ': ' + error.message;
} else if (error.message) { } else if (error.message) {
message += error.message; message += error.message;
@@ -63,12 +67,11 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
return; return;
} }
var ignored = ['name', 'message', 'stack', 'fileName', 'sourceURL', 'line', 'lineNumber', 'column', 'description'];
var result = {}; var result = {};
var empty = true; var empty = true;
for (var prop in error) { for (var prop in error) {
if (j$.util.arrayContains(ignored, prop)) { if (j$.util.arrayContains(ignoredProperties, prop)) {
continue; continue;
} }
result[prop] = error[prop]; result[prop] = error[prop];
+21 -5
View File
@@ -14,28 +14,44 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
}; };
this.originalHandlers = {}; this.originalHandlers = {};
this.installOne_ = function installOne_(errorType) { this.jasmineHandlers = {};
this.installOne_ = function installOne_(errorType, jasmineMessage) {
function taggedOnError(error) {
error.jasmineMessage = jasmineMessage + ': ' + error;
var handler = handlers[handlers.length - 1];
if (handler) {
handler(error);
} else {
throw error;
}
}
this.originalHandlers[errorType] = global.process.listeners(errorType); this.originalHandlers[errorType] = global.process.listeners(errorType);
this.jasmineHandlers[errorType] = taggedOnError;
global.process.removeAllListeners(errorType); global.process.removeAllListeners(errorType);
global.process.on(errorType, onerror); global.process.on(errorType, taggedOnError);
this.uninstall = function uninstall() { this.uninstall = function uninstall() {
var errorTypes = Object.keys(this.originalHandlers); var errorTypes = Object.keys(this.originalHandlers);
for (var iType = 0; iType < errorTypes.length; iType++) { for (var iType = 0; iType < errorTypes.length; iType++) {
var errorType = errorTypes[iType]; var errorType = errorTypes[iType];
global.process.removeListener(errorType, onerror); global.process.removeListener(errorType, this.jasmineHandlers[errorType]);
for (var i = 0; i < this.originalHandlers[errorType].length; i++) { for (var i = 0; i < this.originalHandlers[errorType].length; i++) {
global.process.on(errorType, this.originalHandlers[errorType][i]); global.process.on(errorType, this.originalHandlers[errorType][i]);
} }
delete this.originalHandlers[errorType]; delete this.originalHandlers[errorType];
delete this.jasmineHandlers[errorType];
} }
}; };
}; };
this.install = function install() { this.install = function install() {
if (global.process && global.process.listeners && j$.isFunction_(global.process.on)) { if (global.process && global.process.listeners && j$.isFunction_(global.process.on)) {
this.installOne_('uncaughtException'); this.installOne_('uncaughtException', 'Uncaught exception');
this.installOne_('unhandledRejection'); this.installOne_('unhandledRejection', 'Unhandled promise rejection');
} else { } else {
var originalHandler = global.onerror; var originalHandler = global.onerror;
global.onerror = onerror; global.onerror = onerror;
+1 -1
View File
@@ -78,7 +78,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
cleanup(); cleanup();
if (j$.isError_(err)) { if (j$.isError_(err)) {
if (!(err instanceof StopExecutionError)) { if (!(err instanceof StopExecutionError) && !err.jasmineMessage) {
self.fail(err); self.fail(err);
} }
self.errored = errored = true; self.errored = errored = true;