Error Handling and 404

960 views
Skip to first unread message

cscade

unread,
Apr 20, 2011, 1:29:23 PM4/20/11
to Express
I am finding myself going around in a very tight little circle trying
to get the hang of Express. Unfortunately this is my initial foray
into node as well, so my stupidity level is nearly off the scale, I'm
sure. In my defense, I am quite fluent in JS.

I am set up to render via jade by default, which is working correctly.
I am trying to set up a custom 404 page, using the "new NotFound"
method described in the documentation. However, when I throw a new
NotFound instance, the function I previously passed to app.error() is
never executed. Instead, (since I am running in 'development') I get
the Express 500 page, which shows "500 NotFound" as the error.

So Express knows I have thrown an instance of NetFound, but is not
giving me an opportunity to handle it with app.error();

app.error(function(){ ... }) is defined after app.configure(), which
in turn contains app.use(app.router). I noted from a previous thread
that this could be the issue, but does not seem to be in my case.

My routes are defined very last in the file.

Furthermore (although I have not yet begin to investigate this), when
I add the route app.get('/*', function(req, res) { throw new
NotFound('Not Found'); }); in order to create the custom 404, it beaks
resource loading for stylesheets etc in matched routes above, as then
they get 500s as well. That route is very last in the file, so I would
have expected it to never be called when a previous route does match
and next() is not called.

I appreciate the help!

vision media [ Tj Holowaychuk ]

unread,
Apr 20, 2011, 4:02:03 PM4/20/11
to expre...@googlegroups.com
hmm tough to see exactly what you are doing without the code. The error callbacks from app.error() are registered when the server is "listening" so they should always be last, and should give you the opportunity to respond based on the error's constructor etc. might help to see some of the code if you are fine with gisting that


--
You received this message because you are subscribed to the Google Groups "Express" group.
To post to this group, send email to expre...@googlegroups.com.
To unsubscribe from this group, send email to express-js+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/express-js?hl=en.




--
Tj Holowaychuk
Vision Media
President & Creative Lead

cscade

unread,
Apr 20, 2011, 4:25:16 PM4/20/11
to Express
Absolutely. I have barely made it past the template Express generates.

In this gist, loading / will render index as expected, although the
browser will get back a 500 when trying to load the css resource.

Loading anything other than / will return the Express "500 NotFound"
page, rather than rendering the custom 404 page.

Gist: https://gist.github.com/932658

Thanks again. Your software is truly inspiring.

On Apr 20, 4:02 pm, "vision media [ Tj Holowaychuk ]" <t...@vision-

vision media [ Tj Holowaychuk ]

unread,
Apr 20, 2011, 5:02:43 PM4/20/11
to expre...@googlegroups.com
ah makes more sense now that I see the code. you have errorHandler() which is the end-point for errors, so when you route "/*" and throw the error, it ends up hitting the errorHandler() and not your app.error() function(s). Typically if you plan on handling errors your self, displaying pages etc you dont need errorHandler()

--
You received this message because you are subscribed to the Google Groups "Express" group.
To post to this group, send email to expre...@googlegroups.com.
To unsubscribe from this group, send email to express-js+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/express-js?hl=en.

cscade

unread,
Apr 20, 2011, 7:46:27 PM4/20/11
to Express
I was so close! I had even attempted switching to production to see if
there was any change in behavior. I did not realize that the presence
of errorHandler directives meant the end of the line for error
handling. Makes sense in retrospect.

Is there an accepted method for excluding resources like images, css,
etc from 404 handling? I only want to throw a custom error on a
primary resource request. I'm assuming via more detailed matching on
the final route via a regular expressio

On Apr 20, 5:02 pm, "vision media [ Tj Holowaychuk ]" <t...@vision-

vision media [ Tj Holowaychuk ]

unread,
Apr 21, 2011, 1:03:35 AM4/21/11
to expre...@googlegroups.com
why would you exclude them? it's still a 404, but you can check the url for whatever you like. Yeah the error handling follows the same rule as middleware, simply passes through them until one decides to respond. errorHandler() always responds, but is nice as a default for development to display the stack trace etc. The only difference between regular middleware and an error handling middleware is the signature of (err, req, res, next) vs (req, res, next)

cscade

unread,
Apr 21, 2011, 8:35:27 AM4/21/11
to Express
I must be missing something fundamental.

Since I am catching my 404s with '/*', and no routes prior to that
route match on public resources like .css, then all requests for .css
files match the final route and return 404s.

Am I throwing 404s the wrong way? I want every resource that exists as
a file to be returned always, regardless of my routes. And then bad
routes and missing files should return 404s.

On Apr 21, 1:03 am, "vision media [ Tj Holowaychuk ]" <t...@vision-

vision media [ Tj Holowaychuk ]

unread,
Apr 21, 2011, 11:19:33 AM4/21/11
to expre...@googlegroups.com
Ah, missed that too, didn't look at your setup close enough. You really need to consider middleware order when configuring express/connect, it's very strategic but the issue you have is because app.router (all your routes) is before static() so your "/*" basically says nothing passed me exists, and when you throw the error static() does not have a chance to check for files because it's not an error handling middleware. In short just move static() up one

Carson Christian

unread,
Apr 21, 2011, 12:11:43 PM4/21/11
to expre...@googlegroups.com
Brilliant. Thank you. I'll be sure to pay close attention to order in the future.

-- 
Carson Christian

Ilya

unread,
Apr 21, 2011, 12:18:15 PM4/21/11
to expre...@googlegroups.com
I have an issue with 404 handling as well, albeit not this particular one.

In my case, I have my routes on top, I don't use errorHandler, I don't use views and below all the routes I have this:

app.get('*', function(req, res){
  throw new NotFound;
});

function NotFound(msg){
  this.name = 'NotFound';
  Error.call(this, msg);
  Error.captureStackTrace(this, arguments.callee);
}

NotFound.prototype.__proto__ = Error.prototype;

app.error(function(err, req, res, next){
//console.log('OMG error:', err.name);
res.sendfile(__dirname + '/public/404.html');
});

So, it works and I get the desired behaviour but my 404 page is served with status 200. Sendfile doesn't seem to support custom status and res.header('Status', 404) before it doesn't change anything.
Please tell me - what am I doing wrong?

Ilya

unread,
Apr 21, 2011, 11:48:20 AM4/21/11
to Express
I, too, have some issues with 404 handling. I want to serve a html
page, I'm not using views, so it's just a straight-up HTML. I'm not
using an errorHandler() and below my routes I have:

app.get('*', function(req, res){
throw new NotFound;
});

function NotFound(msg){
this.name = 'NotFound';
Error.call(this, msg);
Error.captureStackTrace(this, arguments.callee);
}

NotFound.prototype.__proto__ = Error.prototype;

app.error(function(err, req, res, next){
res.sendfile(__dirname + '/public/404.html');
});

Of course, this will treat every error as 404 but for now I'm ok with
that.
Now, I do get the desired behaviour except for one thing: my 404 page
is served with 200 status. I'm guessing that res.sendfile() doesn't
support custom status? Or is there some other, better way of doing
this?
On Apr 21, 11:19 am, "vision media [ Tj Holowaychuk ]" <t...@vision-

Shawn Meng

unread,
Apr 21, 2011, 10:42:09 PM4/21/11
to expre...@googlegroups.com
<code>res.render('404.html', { status: 404, error: 'error descripotion' });</code>

Code above is OK in my app.

--
Frontend Engineer @ imeigu
Sent with Sparrow

Ilya

unread,
Apr 25, 2011, 9:54:20 AM4/25/11
to expre...@googlegroups.com
I didn't realize I can render just HTML without a templating engine. Thanks! I'll try this approach.

mnoble01

unread,
Jan 9, 2014, 3:12:40 PM1/9/14
to expre...@googlegroups.com, csc...@gmail.com

I was also having trouble sending a 404 response with an static html file.  

Found this in the docs (http://expressjs.com/api.html#res.status): 

res.status(404).sendfile('path/to/404.png');

Works just fine! 
Reply all
Reply to author
Forward
0 new messages