Node.js/Express - Render error when page not found


Question

I have the following controller/route definition in Node.js (using Express and Mongoose). What would be the leanest most appropriate way to handle Error when the user requests a page that does not exist?

  app.get('/page/:pagetitle', function(req, res) {
      Page.findOne({ title: req.params.pagetitle}, function(error, page) {
          res.render('pages/page_show.ejs',
            { locals: {
                title: 'ClrTouch | ' + page.title,
                page:page
            }
          });
      });
  });

It currently breaks my app. I believe because I'm not doing anything with the error i'm just passing it to the view like a success?

TypeError: Cannot read property 'title' of null

Thanks much.

1
25
5/17/2012 9:09:25 AM

Accepted Answer

Check out the express error-pages example. The principle is to register your app routes first, then you register a catch all 404 handler for all other requests that do not map to a route. Finally, a 500 handler is registered, as follows:

// "app.router" positions our routes 
// specifically above the middleware
// assigned below

app.use(app.router);

// Since this is the last non-error-handling
// middleware use()d, we assume 404, as nothing else
// responded.

app.use(function(req, res, next){
  // the status option, or res.statusCode = 404
  // are equivalent, however with the option we
  // get the "status" local available as well
  res.render('404', { status: 404, url: req.url });
});

// error-handling middleware, take the same form
// as regular middleware, however they require an
// arity of 4, aka the signature (err, req, res, next).
// when connect has an error, it will invoke ONLY error-handling
// middleware.

// If we were to next() here any remaining non-error-handling
// middleware would then be executed, or if we next(err) to
// continue passing the error, only error-handling middleware
// would remain being executed, however here
// we simply respond with an error page.


app.use(function(err, req, res, next){
  // we may use properties of the error object
  // here and next(err) appropriately, or if
  // we possibly recovered from the error, simply next().
  res.render('500', {
      status: err.status || 500
    , error: err
  });
});
48
5/17/2012 9:10:38 AM

One of the major problems with Node.JS is that there is no clean error catching. The conventional way is usually for every callback function, the first argument is the not null if there is an error, so for example:

function( error, page ){
   if( error != null ){
       showErrorPage( error, req, res );
       return;
   }
   ...Page exists...
}

Things can get ugly after a while with too many callbacks, and I recommend using something like async, so that if there is one error, it goes directly to an error callback.

EDIT: You can also use express error handling.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon