27

I have code like this that will render a jade template without a route defined. Think of this like the express.static but it calls res.render with the url.

app.use(function (req, res, next) {
    try {
        res.render(req.url.substring(1), { title: "No Controller", user: req.session.user });
    } catch (err) {
        console.log(err)
        next();
    }
});

The problem is that res.render() isn't throwing an error. Instead it is rendering an error page. Is there a way to detect a missing template or any rendering errors?

4 Answers 4

49

A better way to do it, instead of requiring fs and having another callback, would be to use render's callback :

res.render(my_page_im_not_sure_it_exists, {}, function(err, html) {
    if(err) {
        res.redirect('/404'); // File doesn't exist
    } else {
        res.send(html);
    }
});
Sign up to request clarification or add additional context in comments.

7 Comments

Great find. Its only in 3.x docs but it works in 2.x as well.
Updated answer to use res.send instead of res.end. 4.x documentation specifically states "If you need to respond with data, instead use methods such as res.send()"
I thought this would generate a 404 if there was an error processing the template, but it doesn't seem to. Anyone care to explain why it does not?
A 404 code is what your server wants to reply to a request to tell the querying browser conventionnaly that the page was not found. At this step, you are the server, and you are free to reply with whatever you want. If you want to send a 404 error instead of redirecting the the /404 url, the correct way to do this is here.
What does the second argument in 'render' indicate? I am talking about the "{}" after "my_page_im_not_sure_it_exists"
|
2

Use fs.exists(p, [callback]) to check if the file exists before calling res.render

http://nodejs.org/docs/latest/api/fs.html#fs_fs_exists_path_callback

Node 0.6.x and older

Use path.exists(p, [callback]) to check if the file exists before calling res.render

http://nodejs.org/docs/v0.6.0/api/path.html#path.exists

1 Comment

With the latest (0.8.x) version of node, you should use fs.exists()
1

Similar to @Augustin Riedinger's answer, the same applies when rendering to variable using renderFile:

var html = jade.renderFile('path/to/file.jade', context, function(err, html) {};

Comments

0

You could use fs.open to check if the template exists.

app.use(function (req, res, next) {
    fs.open(__dirname + '/views/' + req.url.substring(1) + '.jade', 'r', function (err) {
      if(err) {
        console.log(err);
        return next();
      }
      res.render(req.url.substring(1), { title: "No Controller", user: req.session.user });
    }
});

1 Comment

res.render has a bunch of logic for figuring out what jade file to use. I was hoping that I wouldn't need to recreate that logic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.