I have been reading for hours on exception handling in Node. I understand the cons of using uncaughtException
, I understand that shutting down the process is good for preventing any "unknown state" where "anything can happen". I understand that using domains is the way to go, and I understand how to properly implement domains, specifically Explicit Binding...
...but I'm still not getting any results for just basic error handling.
I would like to be able to just catch any uncaught exceptions for the purpose of logging. I don't mind killing the process or anything else deemed "undesirable". I just want a log.
I don't feel like I should have to wrap everything in a try/catch or use some library to emit
errors... please correct me if I'm wrong and I will change my ways.
I am using Node and Express and I have the following simple code:
var express = require('express');
var domain = require('domain');
var serverDomain = domain.create();
serverDomain.on('error', function(err) {
console.log("SERVER DOMAIN ERROR: " + err.message);
});
serverDomain.run(function() {
var app = express();
app.get('/testing', function() {
app.nonExistent.call(); // this throws an error
});
var server = app.listen(8000, function() {
console.log('Listening on port %d', server.address().port);
});
});
The error shows up in the console, but the console never receives the "SERVER DOMAIN ERROR..." message. I have also tried wrapping the request/response in their own domain as well, to no avail. Even more disappointing is the fact that using the following does not work either:
process.on('uncaughtException', function(err) {
console.log('uncaughtException caught the error');
});
Am I doing something wrong? Where do I go from here? How can I catch the above error?
You can use connect-domain.
The problem is that the exception happens during Connect's routing, which has both a try/catch block around its execution, as well as a default error handler which prints out stack trace details when running in a non-production mode. Since the exception is handled inside of Express, it never reaches your outer layer for the domains to handle.
Here is an example why to use connect-domain package instead of domain.
http://masashi-k.blogspot.com/2012/12/express3-global-error-handling-domain.html
var express = require('express');
var connectDomain = require('connect-domain');
var app = express();
app.use(connectDomain());
app.get('/testing', function() {
app.nonExistent.call(); // this throws an error
});
app.use(function(err, req, res, next) {
res.end(err.message); // this catches the error!!
});
var server = app.listen(8000, function() {
console.log('Listening on port %d', server.address().port);
});
This happens because Express handles by itself the errors that may appear and in this way it simplifies your work. See Express Guide for error handling. You should use the structure below to handle the errors that may appear:
app.use(function(err, req, res, next){
console.error(err.stack);
res.send(500, 'Something broke!');
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With