Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling 404, 500 and Exceptions in Node.js and Express

I have a node.js + Express + express-handlebars app. I want to redirect the users to 404 page when they go to a page that does not exists and redirect them to a 500 when there is an internal server error or an exception(without stopping the server). In my app.js I have written the middle ware at the end to perform these tasks.

app.get('*', function(req, res, next) {
    var err = new Error();
    err.status = 404;
    next();
});

//Handle 404
app.use(function(err, req, res, next){
    res.sendStatus(404);
    res.render('404');
    return;
});

//Handle 500
app.use(function(err, req, res, next){
    res.sendStatus(500);
    res.render('500');
});

//send the user to 500 page without shutting down the server
process.on('uncaughtException', function (err) {
  console.log('-------------------------- Caught exception: ' + err);
    app.use(function(err, req, res, next){
        res.render('500');
    });
});

However only the code for 404 works. So if I try to go to an url

localhost:8000/fakepage

it successfully redirects me to my 404 page. The 505 does not work. And for the exception handling, the server does keep running but, it does not redirect me to the 500 error page after the console.log

I am confused by so many solutions online where people seem to implement different techniques for this.

Here are some of the resources I looked at

http://www.hacksparrow.com/express-js-custom-error-pages-404-and-500.html

Correct way to handle 404 and 500 errors in express

How to redirect 404 errors to a page in ExpressJS?

https://github.com/expressjs/express/blob/master/examples/error-pages/index.js

like image 781
codeinprogress Avatar asked Mar 20 '16 11:03

codeinprogress


1 Answers

The process on uncaughtexception is for the application process - not a per request error handler. Note it takes an err in it's callback and res is not passed. It's a global application exception handler. It's good to have that in the event your global code throws.

One option is you can have all your normal routes (don't see in your example), then a non error handler final * route for 404. That's always the last route meaning it has fallen through all the other routes not finding a match ... thus not found. It's not an exception handling case - you conclusively know the path they are requesting has no match since it has fallen through.

How to redirect 404 errors to a page in ExpressJS?

Then the err route can return 500

http://expressjs.com/en/guide/error-handling.html

The problem is you have two error routes so it always hits the first one which hard codes returning a 404.

The express 4 tool creates this pattern:

var users = require('./routes/users');

// here's the normal routes.  Matches in order
app.use('/', routes);
app.use('/users', users);

// catch 404 and forward to error handler
// note this is after all good routes and is not an error handler
// to get a 404, it has to fall through to this route - no error involved
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

// error handlers - these take err object.
// these are per request error handlers.  They have two so in dev
// you get a full stack trace.  In prod, first is never setup

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});
like image 145
bryanmac Avatar answered Oct 11 '22 16:10

bryanmac