0

Here I have a function which through the error.

app.post(
  "/restaurant/product/:product_id/images",
  authOnly(),
  authTo({ restaurant: true }),
  reqParamHandler({
    images: {
      type: "array",
      required: false
    }
  }),
  (req, res, next) => {
    const restaurant_id = req.user.id;
    const product_id = req.params.product_id;
    const image_ids = req.body.images;
    Product.findOne({
      _id: product_id,
      restaurant: restaurant_id
    }).exec((err, product) => {
      if (err) res.sendStatus(500);
      if (product) {
        //Probably we need to check that image_ids belongs to restaurant_id
        product.images = image_ids;
        product.save((err, saved_product) => {
          if (err) {
            res.status(500).json({
              message: err.message
            });
          }
          if (saved_product) {
            bindFiles(req.body.images, restaurant_id)
              .then(() => {
                File.find({ _id: { $in: image_ids } }, (err, files) => {
                  res.json({
                    data: files
                  });
                });
              })
              .catch(err => {
                res.status(500).json({
                  message: err.message
                });
              });
          }
        });
      } else {
        res.status(400).json({
          message: "No product found. Please check parameters and try again."
        });
      }
    });
  }
);

The log looks as follows:

Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:491:11)
    at ServerResponse.setHeader (_http_outgoing.js:498:3)
    at ServerResponse.header (/home/omio/Apps/food/server/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/home/omio/Apps/food/server/node_modules/express/lib/response.js:170:12)
    at ServerResponse.json (/home/omio/Apps/food/server/node_modules/express/lib/response.js:267:15)
    at /home/omio/Apps/food/server/src/restaurant/restaurant.ts:1279:25
    at /home/omio/Apps/food/server/node_modules/mongoose/lib/query.js:3122:9
    at tryCatcher (/home/omio/Apps/food/server/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/omio/Apps/food/server/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/home/omio/Apps/food/server/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/omio/Apps/food/server/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/omio/Apps/food/server/node_modules/bluebird/js/release/promise.js:689:18)
    at Async._drainQueue (/home/omio/Apps/food/server/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/home/omio/Apps/food/server/node_modules/bluebird/js/release/async.js:143:10)
    at Immediate.Async.drainQueues (/home/omio/Apps/food/server/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:794:20)
    at tryOnImmediate (timers.js:752:5)
    at processImmediate [as _immediateCallback] (timers.js:729:5)

Which cause the error NodeJS Error: Can't set headers after they are sent. This is because of the Promise (asynchronous function) i used... Yet don't know how to properly fix it... bindFiles is not setting any headers. Any ideas?

Timothy
  • 3,213
  • 2
  • 21
  • 34
  • 1
    Possible duplicate of [Error: Can't set headers after they are sent to the client](https://stackoverflow.com/questions/7042340/error-cant-set-headers-after-they-are-sent-to-the-client) – Kevin B Apr 10 '18 at 16:04
  • You'll have to figure out which res.json methods are being called when the error is thrown, and then figure out what logic allows that to happen and fix it. I don't see anything obvious in your code at the moment that would cause it, but there are a few openings where it could occur if a callback is called with both an error and a truthy result value (which realistically shouldn't be possible, but you're getting an error, so... ) – Kevin B Apr 10 '18 at 16:07
  • @KevinB the issue is not constant. I know what is causing the problem (going to post the log) ... The promise. So the question is "How to handle asynchronous callbacks responses" – Timothy Apr 10 '18 at 16:15
  • @KevinB thank you for your previous comment. Found which function... And its not the one I was expecting... – Timothy Apr 10 '18 at 16:24
  • The one directly inside product.save in the error handler? (is that file really `1279` lines long?) – Kevin B Apr 10 '18 at 16:30
  • No. It refers to the very last one res.status(400).json({ message: "No product found. Please check parameters and try again." }); – Timothy Apr 10 '18 at 16:33
  • Oh, hah, that makes sense actually. on error, product will be null. you've already responded with a 500 due to the error, then continued to respond with 400 because `product` was null. – Kevin B Apr 10 '18 at 16:33
  • There is a middleware which I removed from the function... Going to put it back so you'll have a look at it – Timothy Apr 10 '18 at 16:35
  • You should add a **return** after: res.status(500).json({ message: err.message }); – giankotarola Apr 10 '18 at 17:41
  • @giankotarola after Kevins answer I was thinking about it.. But I ended up adding **if (!product)** condition instead of **else**. A good point though... – Timothy Apr 10 '18 at 19:37

0 Answers0