Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unhandled rejections in Express applications

I have a lot of ES6 promise based code running inside my express app. If there is an error that is never caught I'm using the following code to deal with it:

process.on('unhandledRejection', function(reason, p) {   console.log("Unhandled Rejection:", reason.stack);   process.exit(1); }); 

This works fine for debugging purposes.

In production however I would like to trigger the 500 error handler, to show the user the standard "Something went wrong" page. I have this catch all error handler that currently works for other exceptions:

app.use(function(error, req, res, next) {   res.status(500);   res.render('500'); }); 

Putting the unhandledRejection inside a middleware does not work as it's async and offen results in a Error: Can't render headers after they are sent to the client.

How would I go about rendering the 500 page on an unhandledRejection?

like image 372
Daniel Avatar asked Oct 29 '15 09:10

Daniel


People also ask

What happens on unhandled promise rejection?

Unhandled Rejections When a promise is rejected, it looks for a rejection handler. If it finds one, like in the example above, it calls the function with the error. Perfect. If there's no rejection handler, the promise throws up its hands and produces a global unhandled rejection error.

What is unhandled rejection error?

The unhandledrejection event is sent to the global scope of a script when a JavaScript Promise that has no rejection handler is rejected; typically, this is the window , but may also be a Worker . This is useful for debugging and for providing fallback error handling for unexpected situations.

How can you deal with error handling in Express JS explain with an example?

For example: app. get('/', (req, res) => { throw new Error('BROKEN') // Express will catch this on its own. }) If getUserById throws an error or rejects, next will be called with either the thrown error or the rejected value.

How do you handle errors in middleware?

The error handling middleware allows us to separate our error logic and send responses accordingly. The next() method we discussed in middleware takes us to next middleware/route handler. For error handling, we have the next(err) function.


1 Answers

Putting the unhandledRejection inside a middleware...often results in a Error: Can't render headers after they are sent to the client.

Make a slight change to your error handler:

// production error handler const HTTP_SERVER_ERROR = 500; app.use(function(err, req, res, next) {   if (res.headersSent) {     return next(err);   }    return res.status(err.status || HTTP_SERVER_ERROR).render('500'); }); 

From the ExpressJS Documentation:

Express comes with an in-built error handler, which takes care of any errors that might be encountered in the app. This default error-handling middleware is added at the end of the middleware stack.

If you pass an error to next() and you do not handle it in an error handler, it will be handled by the built-in error handler - the error will be written to the client with the stack trace. The stack trace is not included in the production environment.

Set the environment variable NODE_ENV to “production”, to run the app in production mode.

If you call next() with an error after you have started writing the response, for instance if you encounter an error while streaming the response to the client, Express’ default error handler will close the connection and make the request be considered failed.

So when you add a custom error handler you will want to delegate to the default error handling mechanisms in express, when the headers have already been sent to the client.

like image 136
Jared Dykstra Avatar answered Sep 22 '22 17:09

Jared Dykstra