Ivan Olvera
Ivan Olvera

Reputation: 1

ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

this is my routes code in express. when i try to delete or post in postman, appear this error in console

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:485:11)
    at ServerResponse.header (/Users/ivanolvera/Movvel/Server/node_modules/express/lib/response.js:771:10)
    at ServerResponse.send (/Users/ivanolvera/Movvel/Server/node_modules/express/lib/response.js:170:12)
    at Query.<anonymous> (/Users/ivanolvera/Movvel/Server/src/routes/modelo.js:56:9)
    at Query.<anonymous> (/Users/ivanolvera/Movvel/Server/node_modules/mysql/lib/Connection.js:526:10)
    at Query._callback (/Users/ivanolvera/Movvel/Server/node_modules/mysql/lib/Connection.js:488:16)
    at Query.Sequence.end (/Users/ivanolvera/Movvel/Server/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
    at Query.ErrorPacket (/Users/ivanolvera/Movvel/Server/node_modules/mysql/lib/protocol/sequences/Query.js:92:8)
    at Protocol._parsePacket (/Users/ivanolvera/Movvel/Server/node_modules/mysql/lib/protocol/Protocol.js:291:23)
    at Parser._parsePacket (/Users/ivanolvera/Movvel/Server/node_modules/mysql/lib/protocol/Parser.js:433:10) {
  code: 'ERR_HTTP_HEADERS_SENT'
}
    // delete by id 

    router.delete("/:idModelo", function(req, res, next) {
      const id = req.params.idModelo;
      const sql = `DELETE * FROM Modelo WHERE idModelo=${id}`;
      pool.query(sql, function(err, row, fields) {
        if (err) {
          res.status(500).send({ error: "Something failed!" });
        }
        res.send("Deleted");
      });
    });

Upvotes: 0

Views: 8337

Answers (3)

Mahesh Aryal
Mahesh Aryal

Reputation: 1

Just return return next(); in your middleware and it will work for sure.

Upvotes: 0

jfriend00
jfriend00

Reputation: 707326

If you're pool.query() encounters an error, then you will call res.send() twice:

   router.delete("/:idModelo", function(req, res, next) {
      const id = req.params.idModelo;
      const sql = `DELETE * FROM Modelo WHERE idModelo=${id}`;
      pool.query(sql, function(err, row, fields) {
        if (err) {
          res.status(500).send({ error: "Something failed!" });     // first time res.send()
        }
        res.send("Deleted");                                        // second time res.send()
      });
    });

Remember, though res.send() finishes off an http response, it does not stop the control flow in Javascript. If there is further code to execute in your function, that code will still run. So, you need either an if/else or a return to stop the res.send("Deleted") from running after you've encountered an error. Here's the return.

   router.delete("/:idModelo", function(req, res, next) {
      const id = req.params.idModelo;
      const sql = `DELETE * FROM Modelo WHERE idModelo=${id}`;
      pool.query(sql, function(err, row, fields) {
        if (err) {
          res.status(500).send({ error: "Something failed!" });
          return;                // <=== add this
        }
        res.send("Deleted");
      });
    });

And, here's an if/else:

   router.delete("/:idModelo", function(req, res, next) {
      const id = req.params.idModelo;
      const sql = `DELETE * FROM Modelo WHERE idModelo=${id}`;
      pool.query(sql, function(err, row, fields) {
        if (err) {
          res.status(500).send({ error: "Something failed!" });
        } else {
          res.send("Deleted");
        }
      });
    });

If you think this "Cannot set headers after they are sent to the client" error is occurring in cases where there was no pool.query() error, then there must be some code somewhere else (perhaps middleware) that is also sending a response and we'd have to see that code in order to help you sort that out.

Upvotes: 2

1baga
1baga

Reputation: 338

router.delete("/:idModelo", function(req, res, next) {
  const id = req.params.idModelo;
  const sql = `DELETE * FROM Modelo WHERE idModelo=${id}`;
  pool.query(sql, function(err, row, fields) {
    if (err) {
      res.status(500).send({ error: "Something failed!" });
      return;
    }
    res.send("Deleted");
  });
});

You forgot to put a return after the first res call. So what happened was it saw ran the first one and since there was no return statement it went ahead to run the second one.

So you can solve you error in 2 ways. put the res.send in the else block or put a return keyword after the res.status. It doesn't have to return anything. You just need to signal to the function that after it sends a response error it should terminate the function.

Upvotes: 0

Related Questions