2

Assuming Node.js v0.10.22 and Express v3. I've been trying to solve a simple problem: when something goes wrong, I'd like to at least display a 500 page and exit the server (since apparently that's the best thing to do - so it can be restarted later).

I can figure it out as far as my own callbacks - I can return an err response and exit gracefully. What I can't figure out are the scenarios below. Everything I read about is either unstable (http://nodejs.org/api/domain.html) or there's many ways of doing things (domains, uncaughtException, middleware err param).

So, when using Node.js + Express framework: what is the best way for me to display a 500 page and exit cleanly when encountering these scenarios?

a) sdfg(); /* non-existant function */

b) sdfg /* syntax error */

c) throw new Error("can't connect to redis"); /* 3rd party throws an error */

Is there a way at all? How do people do it in production? P.S: Yes, I've seen this page: Error handling principles for Node.js + Express.js applications?

Community
  • 1
  • 1
John
  • 35
  • 5
  • I use the Express error handler (item `E` [here](http://stackoverflow.com/a/7151775/893780)) to catch any unhandled errors in my Express routes/middleware. – robertklep Nov 30 '13 at 21:21
  • I tied it. It does not catch all of the above. – John Nov 30 '13 at 22:58
  • 1
    I was wrong @robertklep. After days of messing around with it, it seems domains + middleware should be able to catch all of the above errors - if you setup their order properly. – John Dec 05 '13 at 20:56
  • John, can you please post your solution, it will be really helpful. – Abhinav SInghvi Aug 15 '16 at 16:59

1 Answers1

0

I think you can use error handler in middleware put after app.use(app.router), so you can custom your response.

app.use(function(err, req, res, next){
            // treat as 404
            if (err.message
                && (~err.message.indexOf('not found')
                || (~err.message.indexOf('Cast to ObjectId failed')))) {
                return next()
            }

            //if request accept html request
            if(req.accepts('html')){
                switch(err.status){
                    case 404: res.status(404).render('404', { url: req.url });break;
                    default: case 500: res.status(500).render('500', { error: "Internal Server Error" })
                }
            }else{
                switch(err.status){
                    case 403: res.send(403,  { error: "Forbidden" }); break;
                    case 404: res.send(404, { error: req.originalUrl+' not found' }); break;
                    default:res.send(500,  { error: "Internal Server Error" })
                }
            }
        })
Moch Lutfi
  • 552
  • 10
  • 27
  • Yep, I think I've had the order of middleware wrong all these times. Finally figured it out - a combination of middleware + domains should catch all of the above errors. Thanks. – John Dec 05 '13 at 20:58