1

I'm making a auth system with nodejs and mongoDB(mongoose) and I get Error:

error: UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client at F:\tryMern\index.js:68:13

index.js (important part) :

app.post("/api/auth", (req, res) => {
  if (req.body.username && req.body.pass && req.body.status == "new") {
    User.find({ username: req.body.username }, (err, users) => {
      if (!err) {
        if (users.length > 0) {
          return res.json({ error: "The username is taken." });
        }
      }
    });

    const validReq = validate.validate({
      username: req.body.username,
      pass: req.body.pass,
    });

    if (validReq.error) {
      return res.json({ error: validReq.error.details[0].message });
    }
    bcrypt.hash(req.body.pass, 12).then((hashedPass) => {
      // console.log(hashedPass);
      const user = new User({
        username: req.body.username,
        password: hashedPass,
      });
      user.save().then((user) =>
        res.json({
          status: "OK",
          username: user.username,
          token: jwt.sign({ _id: user._id }, jwtKey),
        })
      );
    });

    return;
  }

  User.find({ username: req.body.username }, (err, users) => {
    if (err) {
      console.log(err);
    } else {
      if (users.length > 0) {
        bcrypt.compare(req.body.pass, users[0].password, (err, hash) => {
          if (hash) {
            return res.json({
              validate: true,
              username: users[0].username,
              token: jwt.sign({ _id: users[0]._id }, jwtKey),
            });
          } else {
            return res.json({ validate: false });
          }
        });
      } else {
        return res.json({ validate: false });
      }
    }
  });
});

when I add The username is taken part the error comes ( the part say find user and if its exist say username is taken) if there is another way to check if user exist please tell or fix this problem thanks :)

EDIT: when i try to submit the user with exist username the response is { "error": "The username is taken." } and the error come

1
  • You're not using asynchronous code and callbacks properly. E.g. your code about validation in line 11 gets executed before the callback for User.find defined as of line 3ff gets called. This way e.g. it may happen that you call res.send in line 6 AND 17. This causes the error Headers already set because they were set already and the response has already been sent. I recommend you reading about asynchronous code, callbacks and async/await in JavaScript. Commented Dec 25, 2020 at 10:41

1 Answer 1

1

I fix this:


app.post("/api/auth", (req, res) => {
  if (req.body.username && req.body.pass && req.body.status == "new") {
    User.find({ username: req.body.username }, (err, users) => {
      if (!err) {
        if (users.length > 0) {
          res.json({ error: "The username is taken." });

          return;
        }
        const validReq = validate.validate({
          username: req.body.username,
          pass: req.body.pass,
        });

        if (validReq.error) {
          return res.json({ error: validReq.error.details[0].message });
        }
        bcrypt.hash(req.body.pass, 12).then((hashedPass) => {
          // console.log(hashedPass);
          const user = new User({
            username: req.body.username,
            password: hashedPass,
          });
          user.save().then((user) =>
            res.json({
              status: "OK",
              username: user.username,
              token: jwt.sign({ _id: user._id }, jwtKey),
            })
          );
        });
      }
    });

    return;
  }

  User.find({ username: req.body.username }, (err, users) => {
    if (err) {
      console.log(err);
    } else {
      if (users.length > 0) {
        bcrypt.compare(req.body.pass, users[0].password, (err, hash) => {
          if (hash) {
            return res.json({
              validate: true,
              username: users[0].username,
              token: jwt.sign({ _id: users[0]._id }, jwtKey),
            });
          } else {
            return res.json({ validate: false });
          }
        });
      } else {
        return res.json({ validate: false });
      }
    }
  });
});
Sign up to request clarification or add additional context in comments.

1 Comment

Nice! You might also mark this answer as accepted. Accepting answers and upcoming comments or answers helps the community to see what is valuable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.