0

So far, I have checked that to handle error for promise in generic way, unhandledRejection event handler is the best way to do it. Just like below:

process.on('unhandledRejection', (reason,promise) => {
console.log('error: unhandledRejection');
});

Now the challenge comes when I want to access Request and Response Objects inside this event handler. So that I can generate the 500 Response in generic way and hence I wont need to add promise exception handling everywhere in the project.

I have been suggested to use:

app.use(function (req, res, next) {
process.on('unhandledRejection', function (reason,promise) {
console.error("Here I can access request objects.")
// Unregister unhandledRejection
});
});

But in above case the event listener will be registered multiple times and will only be unregistered whenever exception occurred. As the event will be registered multiple times, So the code(console.error("Here I can access request objects.")) will be triggered multiple times.

Any suggestions ? If I can access request and response objects out side the app.use?

Thanks in Advance!

Mehakpal Singh
  • 146
  • 1
  • 2
  • 11

1 Answers1

0

By default express does handle the error. By express documentation:

Express comes with an embedded error handler that will take care of any errors that may occur in the application. This default error-handling middleware function is added at the end of the middleware function stack.

next() If you give an error to the function and do not process it in a custom error handler, this error is handled by the embedded error handler; the error is printed on the client with stack-trace. Stack-trace is not included in the production environment.

Set the NODE_ENV value of the environment variable to production to run the application in production mode .

When an error is printed, the following information is added to the response:

  • res.statusCodethe value of the err.statusfield comes from the field (or err.statusCode). If this value is not in the range of 4xx or 5xx, it will be set to 500.

  • res.statusMessage field is set according to the status code.

  • If in production mode, the body (body) becomes the HTML of the status code message, otherwise err.stack.

  • err.headers Any header specified in object.

next() If you call the function with an error after starting to write the response (for example, if you encounter an error while transmitting the response to the client) the default Express error handler will close the connection and fail the request.

When you add a custom error handler, you should authorize the default Express error handler if the headers have already been sent to the client:

function errorHandler (err, req, res, next) {
  if (res.headersSent) {
    return next(err)
  }
  res.status(500)
  res.render('error', { error: err })
}

Calling the next()function multiple times with an error in your code can trigger the default error handler, even if the custom error handler middleware is in place.

This is prone to memory leak:

app.use(function (req, res, next) {
process.on('unhandledRejection', function (reason,promise) {
console.error("Here I can access request objects.") // Unregister unhandledRejection
}); });

Also, you can't access the response object in 'unhandledRejection', and why do you want to access that if express can handle that for you to send '500' status code to the user. It is always a good practice to catch promises whenever and wherever required. However, if some promises are still not covered there are libraries to handle it too like : express-promise-router, express-async-errors

We could emit meaningful error response with err argument in express error handler and the response will be sent to the user. for example,

app.use((err, req, res, next) => {
  if (err.name === 'CustomError' && err.message === 'EmptyResponse') {
    return res.status(404).send('Not Found');
  }
  // ... more error cases...
  return res.status(500).send('Internal Server Error');
});
Apoorva Chikara
  • 8,277
  • 3
  • 20
  • 35
  • I am using promises(then), in my code. So here is an example: ```'Some Query'.then((response) => "Use this response") ``` Suppose while executing query I got an error, I don't want to catch such errors again and again for every query I am firing, So to do that, I want to apply a generic exception handling and when it is caught in generic way, I want to send an email which should contain the details of the error and request parameters, which are only possible in case I can access the request object. – Mehakpal Singh Mar 03 '21 at 10:57
  • 1
    This error is not something which comes in due to data discrepancy in request object if it is related to that you should configure an error service and pass error message to it and the discrepancy in data. This is something which comes and will come in every promise if you won't handle the errors in it. It won't break your app so you don't need to send internal server error. If you want to send email you should use nodemailer. I would suggest you to create a controller for executing all query dynamically and attach catch to it. I would recommend you to use catch with every promise. – Apoorva Chikara Mar 03 '21 at 11:12