Recover from Uncaught Exception in Node.JS

Problem

OK, so I have a problem. If an uncaught exception occurs while I am handling an HTTP request, I have no opportunity to call the end() method on the http.ServerResponse object. Therefore, the server hangs forever and never fulfills the request.

Here's an example:

var express = require('express');
var app = express.createServer();
var reqNum = 0;
app.get('/favicon.ico', function(req, res) {res.send(404);});
app.get('*', function(req, res, next) {
    console.log("Request #", ++reqNum, ":", req.url);
    next();
});
app.get('/error', function(req, res, next) {
    throw new Error("Problem occurred");
});
app.get('/hang', function(req, res, next) {
    console.log("In /hang route");
    setTimeout(function() {
        console.log("In /hang callback");
        if(reqNum >= 3)
            throw new Error("Problem occurred");
        res.send("It worked!");
    }, 2000);
});
process.on('uncaughtException', function(err) {
    console.log("Uncaught exception!", err);
});
app.listen(8080);

If you visit /error, an exception occurs, but it is caught. The user receives an error message - no problem. If I visit /hang, though, the server will eventually throw an uncaught exception and hang forever. Any subsequent requests for /hang will hang.

This sucks. Any advice for how to fix this issue?

Problem courtesy of: BMiner

Solution

When an uncaught exception occurs, you're in an unclean state. Let the process die and restart it, there's nothing else you can do to safely bring it back to a known-good state. Use forever, it'll restart your process as soon as it dies.

Solution courtesy of: thejh

Discussion

Use try/catch/finally.

app.get('/hang', function(req, res, next) {
    console.log("In /hang route");
    setTimeout(function() {
        console.log("In /hang callback");
        try {
            if(reqNum >= 3)
                throw new Error("Problem occurred");
        } catch (err) {
            console.log("There was an error", err);
        } finally {
            res.send("It worked!");
        }
    }, 2000);
});
Discussion courtesy of: fent

This recipe can be found in it's original form on Stack Over Flow.