How to render a 500 response after an uncaught error in express 4?

app.get('/', function(req, res) {
   doSomethingAsync(function(err) {
      throw new Error('some unexpected/uncaught async exception is thrown');
   })
})

Possibly unhandled Error: some unexpected/uncaught async exception is thrown
    at ...stacktrace...:95:9
From previous event:
    at ...stacktrace...:82:6)
    at ...stacktrace...:47:6)
    at ...stacktrace...:94:18)

I have tried a bunch of domain middlewares however they all only work for express 3. I am currently on express 4.5 and I am wondering if express had changed that domain no longer works.

Currently, when an exception is thrown, the response basically hangs until a timeout.

assume the error you got is inside router or controller put this in very end of your app configuration, before listening

app.use(function(err, req, res) {
    res.status(err.status || 500);
    // if you using view enggine
    res.render('error', {
        message: err.message,
        error: {}
    });
    // or you can use res.send();        
});

your app will catch any uncaught router error and will render "error" page

by the way do not forget to include "next" in your router Initialization


Edited

app.get('/', function(req, res, next) {
    try {
        signin(req.query.username, req.query.password, function(d){
            if (d.success) {
                req.session.user = d.data; 
            } 
            res.end(JSON.stringify(d));
        });
    } catch(e) {
        next(e);
    }
}

Hope it help

As you have found, trying to try/catch an asynchronous function doesn't work. Domains should work just fine in express 4 (or express 3, or straight http, whatever). I've never used any express middleware that attempts to implement domain handling though, so I can't really speak to how well they do or don't work.

I'd suggest just implementing domain handling on your own; it's not that bad. One of the better examples of using domains is right in node's documentation on domains (not the first bad example they show, the second, good one). I strongly recommend reading those docs.

The basic idea is pretty simple:

  1. Create a domain
  2. Add an error handler
  3. Call domain.run(function() { ... }) putting the code you want inside the domain in that run callback.

An extremely simple (and very localized) example:

// This will alwas throw an error after 100ms, but it will still
// nicely return a 500 status code in the response.

app.get('/', function(req, res) {
    var d = domain.create();
    d.on('error', function(err) {
        res.status(500).send(err.message);
    });
    d.run(function() {
        setTimeout(function() {
            throw new Error("some unexpected/uncaught async exception");
        }, 100);
    });
});

So, that will work and it might be enough for your case, but it's not the best solution (If you've read the docs, you might notice that it's pretty darn close to their bad example). The problem is (from the docs again):

By the very nature of how throw works in JavaScript, there is almost never any way to safely "pick up where you left off", without leaking references, or creating some other sort of undefined brittle state.

The best solution (as far as I'm aware anyway) is to do what's recommended in the node docs. The basic idea that they suggest is to use cluster (or something similar) to start multiple worker processes which run your web server from a master process. In each of those worker processes, setup a domain which will nicely send back a 500 status when an error is thrown and then exit. Then, in the master process, detect when a worker exits and simply start up a new one.

What that does is eliminate any problems with "picking up where you left off" by simply restarting the entire process when there's a thrown error, but only after handling it gracefully.

Putting an example of that in a SO answer is probably a bit much, but there really is a great example right in the node docs. If you haven't already, go take a look at it. :)