1
exports.getTour = catchAsync(async (req, res, next) => {
  const tour = await Tour.findById(req.params.id);

  if (!tour) {
    next(new AppError('No tour found with that ID', 404));
  }

  res.status(200).json({
    status: 'success',
    data: {
      tour
    }
  });
});

if tour variable is empty I am invoking the next() method and creating an error inside it using a class constructor but even after invoking the next() the response was sent as a response to the request, and then i am getting '[ERR_HTTP_HEADERS_SENT]:' error. Why the block is not exiting even after next is called?

somesh
  • 63
  • 7
  • 2
    You can either `return` an empty statement inside the `if` condition or make the `res.status().json()` invocation inside an `else`. – ryeballar Apr 26 '21 at 04:43

3 Answers3

2

Because you need to return in order to breakout of the function if tour is empty.

So do this

if (!tour) {
  return next(new AppError('No tour found with that ID', 404));  
}
fortunee
  • 3,852
  • 2
  • 17
  • 29
1

next() makes a current call back function pass to the next request which has the same URL. Requests couldn't be finished if the response is not activated in the call back function. To finish a call back function, a response should be written with any function. To use next() at the call back there should be another request like,

// request to be passed by `next()`
app.request('same URL', (res, req) => {

...

res.end()

});

This is an example on express document about next().

If you want to finish with sending an error then just respond with JSON res.status(404).send("error": "No tour found with that ID").

jacobkim
  • 1,043
  • 10
  • 20
-1

in a middleware, you should execute the next() function, try

module.exports.getTour = async (req, res, next) => {
  const tour = await Tour.findById(req.params.id);
  if (!tour) res.send("No tour found with that ID");

  req.tour = tour;

  next();
};