Billy Moon
Billy Moon

Reputation: 58521

Better routing for nodejs express

I am new to express, and got a page up and running with...

/*
 * Module dependencies
 */
var express = require('express'),
  stylus = require('stylus'),
  nib = require('nib'),
  app = express(),
  fs = require('fs'),
  path = require('path')

function compile(str, path) {
  return stylus(str).set('filename', path).use(nib())
}

app.set('views', __dirname + '/views')
app.set('view engine', 'jade')
app.use(express.logger('dev'))
app.use(stylus.middleware({
  src: __dirname + '/public',
  compile: compile
}))

app.use(express.static(__dirname + '/public'))

app.get('/', function(req, res) {
  res.render('index', {
    title: 'Home'
  })
})

app.use(function(req, res, next){

  // test if te file exists
  if(typeof fs.existsSync != "undefined"){
    exists = fs.existsSync
  } else {
    exists = path.existsSync
  }

  // if it does, then render it
  if(exists("views"+req.url+".jade")){
    res.render(req.url.replace(/^\//,''), { title: 'Home' })

  // otherwise render the error page
  } else {
    console.log("views"+req.url+".jade")
    res.render('404', { status: 404, url: req.url, title: '404 - what happened..?' });
  }

});

app.listen(3000)

The problem I am having, is that I have used a very poor check of the filesystem to determine if a page exists or not. I assume there is a much better way to handle this, but my googling has not yielded any results.

If I try to use app.error it gives me an undefined message.

I really just want to try to render any address given, and then catch errors, without the filesystem reading step.

Upvotes: 0

Views: 858

Answers (1)

robertklep
robertklep

Reputation: 203241

You could install an error handler which will catch errors:

app.use(function(err, req, res, next) {
  // ... handle error, or not ...
  next(); // see below
});

Ideally, you should place this as close to app.listen() as possible, to make it one of the last middlewares in the chain. When you do, your 'generic' handler can look like this:

app.use(function(req, res, next) {
  res.render(req.url.replace(/^\//,''), { title: 'Home' });
});

If you call next() in the error handler (instead of somehow generating an error page), the failed request will eventually result in a 404 (Not Found) error. Depending on your situation, this might or might not be okay. Also, all errors will get caught, not just missing template files.

Upvotes: 1

Related Questions