Search code examples
node.jsexpresserror-handlinguncaught-exception

Express 4 / Node JS - Gracefully managing uncaughtException


I try my very best to ensure that there are no errors in my code, but occasionally there is an uncaught exception that comes along and kills my app.

I could do with it not killing the app, but instead output it to a file somewhere, and try to resume the app where it left off - or restart quietly and show a nice message to all users on the application that something has gone wrong and to give it a sec while it sorts itself out.

In the event of the app not running, it'd be good if it could redirect it to somewhere that says "The app isn't running, get in touch to let me know" or something like that.

I could use process.on('uncaughtException') ... - but is this the right thing to do?

Thank you very much for taking the time to read this, and I appreciate your help and thoughts on this matter.


Solution

  • You can't actually resume after a crash, not at least without code written specifically for that purpose, like defining state and everything.

    Otherwise use clusters to restart the app.

    // ... your code ...
    
    var cluster = require('cluster');
    process.on('uncaughtException', function(err){
        //.. do with `err` as you please
        cluster.fork(); // start another instance of the app
    });
    

    When it forks, how does it affect the users - do they experience any latency while it's switching?

    Clusters are usually used to keep running more than a single copy of your node app at all times, so that while one of the workers respawns, others are still active and preventing any latency.

    if (cluster.isMaster)
        require('os').cpus().forEach(cluster.fork);
    
    cluster.on('exit', cluster.fork);
    

    Is there anything that I should look out for, e.g. say there was an error connecting to the database and I hadn't put in a handler to deal with that, so the app kept on crashing - would it just keep trying to fork and hog all the system resources?

    I've actually not thought about that concern before now. Sounds like a good concern.

    Usually the errors are user instigated so it's not expected to cause such an issue.

    Maybe database not connecting issue, and other such unrecoverable errors should be handled before the code actually goes into creating the forks.

    mongoose.connection.on('open', function() {
        // create forks here
    });
    mongoose.connection.on('error', function() {
        // don't start the app if database isn't working..
    });
    

    Or maybe such errors should be identified and forks shouldn't be created. But you'll probably have to know in advance which errors could those be, so you could handle them.