Reputation: 5233
Is there any way in node.js
to log all exceptions?
process.on('uncaughtException')
is not enough for me, because I need to log all caught and uncaught exceptions, even if there was a catch
somewhere in the code which just ignored/swallowed the error.
Do you guys think, it is possible in node.js
?
Upvotes: 3
Views: 1576
Reputation: 13570
One hacky way to do this is using debug context:
const vm = require('vm');
const Debug = vm.runInDebugContext('Debug'); // Obtain Debug object
Debug.setListener((type, _, e) => { // listen for all debug events
if (type == Debug.DebugEvent.Exception) {
console.log(e.exception().stack) // e is an event object
}
});
Debug.setBreakOnException(); // this is required for Exception event to fire
try {
throw new Error('bla');
} catch(e) {
// ha
}
Warning: don't leave this code in production, use for debugging only.
Obviously, it won't call asynchronous errors, because they are not actually thrown, they are just created to passed to a callback.
Another way is to replace possible error constructors:
const OldError = Error;
const MyError = function(message) {
const err = new OldError(message);
OldError.captureStackTrace(err, MyError); // remove top frame from stack trace
console.log(err.stack);
return err;
}
MyError.prototype = Error.prototype; // Fix instanceof
global.Error = MyError;
try {
throw new Error('bla');
} catch(e) {
}
new Error('blabla');
This way you can also handle asynchronous error, but won't see if something other than instance Error
is thrown.
If you are interested only in promises and you are using native v8 promises, then you can try this:
const vm = require('vm');
const Debug = vm.runInDebugContext('Debug');
Debug.setListener((type, _, e) => {
if (type == Debug.DebugEvent.PromiseEvent) {
if (e.status() === -1) { // 0=pending, 1=resolved, -1=rejected
console.log(e.value().value().stack);
}
}
});
Promise.reject(new Error('test'))
.catch(() => {});
It will likely generate some duplicates, since it catches child promise rejection as well as original promise rejection.
Upvotes: 6
Reputation: 6898
You could attach a debugger like node-inspector and active the option in node-inspector. This does not log exceptions but pause execution which should be enough to find the quirks in the 3rd party module.
If you're using WebStorm you can log uncaught exceptions to the console or to a file. After starting the WebStorm debugger open the breakpoints dialog and activate the "Any exception" setting for "JavaScript Exception Breakpoints" and breakpoint actions according to
Upvotes: 1
Reputation: 11337
If you are swallowing the exceptions you cannot track them. If you think that a module that you're using is ignoring the exceptions you are using a bad module or you are not using it correctly.
If you are using Express the correct approach will be to redirect all the exception and errors with next(err)
.
The exceptions will be passed to the error handler (note the four parameters in the function) and there you can log them:
router.get('/', function (req, res, next) {
// your logic
if(err) {
return next(err);
}
return next();
});
// Error handler
app.use(function(err, req, res, next) {
console.log(err.stack);
res.status(err.status || 500).json({
error: {
code: err.code,
message: err.message
}
});
next(err);
});
Upvotes: 0