简体   繁体   中英

Cannot set headers after they are sent to the client using nodejs mysql

What I am attempting to do is write a statement to check if email exists in my mysql database when a user registers. In postman it sends me the correct error message of "user already taken" however the server crashes after and displays "cannot set headers after they are sent to the client." I have read similar posts but did not help.

//The following code is in my user.service.js file:

const pool = require("../../config/database");

module.exports = {

  //Create new user
  createUser: (data, callBack) =>{
    pool.query(
      `insert into registration(name, email, password, confirm_password)
              values(?,?,?,?)`,
    [
      data.name,
      data.email,
      data.password,
      data.confirm_password
    ],
    (error, results, fields) =>{
      if(error){
        return callBack(error);
      }
      return callBack(null, results);
    }
    );
  }
}

//The following code is in my user.controller.js file:

const {
  createUser,
} = require("./user.service");
const pool = require("../../config/database");


module.exports = {
  
  createUser: (req, res) =>{
    const body = req.body;
    const salt = genSaltSync(10);
  pool.query('SELECT email FROM registration WHERE email = ?', [body.email], (error, results) =>{
    if(error){
      console.log(error);
    }
    if(results.length > 0){
      return res.status(400).json({
        message: 'User already taken'
      })
    }
  })
    createUser(body, (err, results) => {
      if(err){
        console.log(err);
        return res.status(500).json({
          success:0,
          message:"Error in database connection"
        });
      }
      return res.status(200).json({
        success: 1,
        message: `User ${results.insertId} signed up successfully`,
        data: results
      });
    });
  }

}

//The following code is from user.router.js file:

const {
  createUser,
} = require("./user.controller");
const router = require("express").Router();

router.post("/signup", createUser);

module.exports = router;

In your createUser function that is executed on the post request you are doing two things. First you check whether a user with the provided email exists and, second, you create a user. However, those functions are not executed consecutively, instead they are running simultaneously and thus create a race condition.

So going off on your example, if the email check query SELECT email FROM registration WHERE email = ? is faster and the user already exists, it will respond with:

  return res.status(400).json({
    message: 'User already taken'
  })

but the createUser function (below) is still running and once it is finished, it will try to also send a response. Therefore, you are presented with an application crash in the console even though in the postman you can see the response stating that the user already exists.

In order to fix this error you should execute the createUser function only if the results.length is 0 inside the callback provided to the email check query, like so:

createUser: (req, res) => {
    const body = req.body;
    const salt = genSaltSync(10);
  pool.query('SELECT email FROM registration WHERE email = ?', [body.email], (error, results) =>{
    if(error){
      console.log(error);
    }

    if(results.length > 0){
      return res.status(400).json({
        message: 'User already taken'
      })
    }

    createUser(body, (err, results) => {
      if(err){
        console.log(err);
        return res.status(500).json({
          success:0,
          message:"Error in database connection"
        });
      }
      return res.status(200).json({
        success: 1,
        message: `User ${results.insertId} signed up successfully`,
        data: results
      });
    });
  })
}

Now you execute the createUser function only if a user with the provided email doesn't exist, which effectively removes the race condition between the two functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM