5

I am creating a Nodejs and express based backend application and trying to handle error in a manner which is suitable for production systems.

I use async await to handle all synchronous operations in the code.

Here is a code snippet of router end points

app.get("/demo",async (req, res, next) => {
 await helper().catch(e => return next(e))
 console.log("After helper is called")
 res.json(1)
})

function helper(){ //helper function that throws an exception
 return new Promise((resolve, reject)=> reject(new Error("Demo Error")))
}

After all routes are defined I have added a common error handler that catches exceptions. To simplify it I am adding a simple function

routes.use( (err, req, res, next) => {
  console.log("missed all", err)

 return res.status(500).json({error:err.name, message: err.message});
});

I expect that the code after await helper() should not execute since the exception has been handled and response sent to frontend. Instead what I get is this error.

After helper is called
(node:46) UnhandledPromiseRejectionWarning: Error 
[ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the 
client

What is the correct way to handle error with async await?

Kartik Jain
  • 109
  • 2
  • 9
  • You can have a look at this answer https://stackoverflow.com/questions/48685872/how-to-properly-implement-error-handling-in-async-await-case – Shubham raj Mar 27 '19 at 13:58

2 Answers2

1

you can use try catch to handle the situation

app.get("/demo",async (req, res, next) => {
 try {
  await helper()
  console.log("After helper is called")
  res.json(1)
 } catch(err) {
  next(err)
 }
})

function helper(){ //helper function that throws an exception
 return new Promise((resolve, reject)=> reject(new Error("Demo Error")))
}
ajai Jothi
  • 2,284
  • 1
  • 8
  • 16
1

You get After helper is called, because your code continues to execute since it did not return

Don't chain catch with async/await. You do that with Promise.

helper()
  .then(data => console.log(data))
  .catch(e => console.log(e))

You can handle error like:

app.get("/demo",async (req, res, next) => {
  try {
    await helper();
    // respond sent if all went well
    res.json(something)
  catch(e) {
    // don't need to respond as you're doing that with catch all error handler
    next(e)
  }
})
1565986223
  • 6,420
  • 2
  • 20
  • 33