1

I've been trying to figure out this error for hours. I think I know why it is happening. The res.json() and res.cookie() both send responses, I just don't know how to fix it.

The error I am getting is whenever the endpoint is called, the server crashes with error:

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

Here is my javascript code (I'm using express and node and this is the function that is called as per a route.

const User = require('../models/User')
const Session = require('../models/Session')
const asyncHandler = require('express-async-handler')
const bcrypt = require('bcrypt')

function generateSessionId() {
    const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    let sessionId = '';
    for (let i = 0; i < 256; i++) {
      sessionId += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return sessionId;
}

// @desc Create new user
// @route POST /users
// @access Private
const createNewUser = asyncHandler(async (req, res) => {
    const SESSION_EXPIRY_TIME = 30 * 24 * 60 * 60 * 1000;

    const {username, password, grade, zip, role, industry} = req.body;

    // Confirm Data
    if((username === null) || (password === null) || (grade === null) || (zip === null) || (role === null) || (industry === null)) {
        return res.status(400).json({message: 'All fields are required'});
    }

    // Check for Duplicate
    const duplicate = await User.findOne({username}).lean().exec()
    if (duplicate) {
        return res.status(409).json({message: 'Duplicate username'});
    }
    
    var hashedPwd = "";
    if(password){
        hashedPwd = await bcrypt.hash(password, 10);
         // Password Hash
    }
    else {
        return res.status(400).json({message: 'All fields are required'});
    }

    var sessionId = generateSessionId();
    req.session.sessionId = sessionId;
    const expiryDate = new Date(Date.now() + SESSION_EXPIRY_TIME);

    res.cookie('sessionId', req.session.sessionId, {
        expires: expiryDate,
        sameSite: 'lax',
    });

    // Create and Store User
    const newUser = new User({username, password: hashedPwd, role: role, zip: zip, grade: grade, industry: industry});
    newUser.save()
        .then((result) => {
            const newSession = new Session({sessionId: sessionId, userId: username, expires: expiryDate});
            newSession.save();
            
            return res.status(201).json({message: "New user ${username} created"});
        })
        .catch((error) => {
            console.log(error);
            return res.status(500).json({message: "Internal server error"});
        })
})

module.exports = {
    createNewUser,
}

Any help would be great!

PraneethO
  • 15
  • 3
  • `res.cookie()` does not send a response, it sets a response header. You'll need to call `res.cookie()` before `res.json()` since the latter finalises the response – Phil Mar 27 '23 at 01:20
  • @Phil Yup I changed it so that the cookie is called before json, but it still doesn't work (I'm getting the same error) – PraneethO Mar 27 '23 at 11:25
  • You'll need to [edit] your question to show what you changed – Phil Mar 27 '23 at 12:18
  • Done, the res.cookie is called before, but I'm still getting the same error. – PraneethO Mar 27 '23 at 20:20
  • Can't see any obvious issues. Have you made sure you restarted Express after making the changes? – Phil Mar 27 '23 at 20:24
  • Is the error accompanied by a stack trace? Does it indicate which line of your code is trying to set headers? – Phil Mar 27 '23 at 20:25

0 Answers0