Erik
Erik

Reputation: 14770

How to handle error in nodejs behind nginx?

I have nodejs/expressjs application that handles behind nginx. In the expressjs application I have the following error handling middleware:

app.use(function(req, res, next){
  res.status(404);

  // respond with json
  if (req.accepts('json')) {
    res.send({ error: 'Not found' });
    return;
  }

  // respond with html page
  if (req.accepts('html')) {
    res.render('404', { url: req.url });
    return;
  }

  // default to plain-text. send()
  res.type('txt').send('Not found');
});

app.use(function(err, req, res, next){
  res.status(err.status || 500);

  // respond with json      
  if (req.accepts('json')) {
    res.send({ error: 'Not found' });
    return;
  }

  // respond with html page
  if (req.accepts('html')) {
    res.render('500', { error: err });
    return;
  }

  res.type('txt').send('Internal error');
});

Also in nginx I have the following config for error handling:

error_page 404 /404.html;
location = /404.html {
  internal; 
  root /path/to/static/html/;
}

error_page 400 500 502 503 504 /50x.html;         
location /50x.html {                 
  internal;                 
  root /path/to/static/html/;         
}

When I try to send some error by nodejs likes the following

res.status(500).json({error: 'Something happened'});

this error handles nginx and I get full html error page response instead json response. I think this is due the following nginx config:

error_page 400 500 502 503 504 /50x.html;         
location /50x.html {                 
  internal;                 
  root /path/to/static/html/;         
}

How could I setup nginx to handle only errors that not handled by nodejs server?

Thanks.

Upvotes: 3

Views: 3344

Answers (1)

Alexey Ten
Alexey Ten

Reputation: 14354

You're using proxy_intercept_errors on directive. In order to intercept only certain error codes, just add error_page directive(s) to location with proxy. Otherwise they are inherited.

Here we only intercept only 400 and 502 errors, everything else will pass through to client.

location / {
    proxy_pass http://myapp_upstream;
    proxy_intercept_errors on;
    error_page 400 502 /50x.html;
}

Upvotes: 8

Related Questions