"Cannot set headers after they are sent to the client." but i m using 'return' statements

Issue

I have a weird issue in NodeJS, Express and sequeilize. I was refactoring try/catch statements I facing this error. Specially, in postman when I send a signup post its work well but server is going to be shutting down.
enter image description here
enter image description here

I’ve already read enough of other solution, I used the return statement. but it still seems to be asynchronous somewhere. maybe… but I cant find that in the sentence..

I ever read that
(‘https://www.codementor.io/@oparaprosper79/understanding-node-error-err_http_headers_sent-117mpk82z8’)

  signUpController: async (req, res) => {
    const { username, email, password, social } = req.body
    const userInfo = await user.findOne({
      where: {
        email: email,
        username: username,
        social: social
      },
    });
    try{
        if(userInfo === null){
          const newUser = await user.create({
            username,
            email,
            social : null,
            password: bcrypt.hashSync(password, salt),
            profileimage: "default",
            total_time: 0,
          });
          return res.status(200).json(newUser);
        }
      }catch(err){
        return res.status(400).json({message : "invalid access"});
      }
      finally{
        return res.status(401).json({ message : "already exist"});
      }    
}

Solution

Like @somethinghere said, the finally block always executes, regardless of whether an error is thrown or not. You’re trying the condition if( userInfo !== null ) but the error still occurs, so I guess userInfo is a falsy value but doesn’t strictly equal to null.

Because you’re trying to refactor the code, I suggest the exit early pattern where you handle all invalid cases before the happy one. You can see my code below:

signUpController: async (req, res) => {
    const { username, email, password, social } = req.body
    const userInfo = await user.findOne({
        where: {
            email: email,
            username: username,
            social: social
        },
    });
    try {

        if (userInfo) {
            // early exit
            return res.status(401).json({ message: "already exist" });
        }

        // you don't need else here
        const newUser = await user.create({
            username,
            email,
            social: null,
            password: bcrypt.hashSync(password, salt),
            profileimage: "default",
            total_time: 0,
        });
        return res.status(200).json(newUser);
    }
    catch (err) {
        return res.status(400).json({ message: "invalid access" });
    }
    
    // you don't need the finally block 
}

Answered By – Đăng Khoa Đinh

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published