genericUser
genericUser

Reputation: 7128

Error: Can't set headers after they are sent. NodeJS used async function

I faced to a little problem which blocks me. I'm working on authentication user service for my app used Node.js. I'm working on a PUT user route and need to compare the old and new password used bcrypt.

Sense adding a comparative try/catch I'm getting the following error:

Error: Can't set headers after they are sent.

app.put(`/users/:email`, checkAuthenticated, envisionDuplicateEmails, async (req, res) => {
  const accountEmail = req.params.email
  body = req.body
  const user = users.find((user) => user.email === accountEmail)
  const index = users.indexOf(user)

  if (!user) {
    res.status(500).send('Account not found.');
  } else {

    try {
      if (await bcrypt.compare(body.password, user.password)) {
        body.password = user.password
      } else {
        const hashedPassword = await bcrypt.hash(body.password, 10)
        body.password = hashedPassword
      }
    } catch (e) {
      return res.status(500).send('Internal server error');
    }

    const updatedAccount = { ...user, ...body }
    users[index] = updatedAccount
    res.redirect('/')
  }
})

utility functions:

function checkAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    return next()
  }
  res.redirect('/login')
}

function envisionDuplicateEmails(req, res, next) {
  accountEmail = req.params.email
  bodyEmail = req.body.email

  if (bodyEmail) {
    if (bodyEmail != accountEmail) {
      checkEmailExist(req, res, next)
    }
  }
  return next()
}

function checkEmailExist(req, res, next) {
  const accountEmail = req.body.email
  const getAccount = users.find((user) => user.email === accountEmail)

  if (getAccount === undefined) {
  } else {
    return res.status(500).send({ 'message': 'Account email already exist' })
  }
  return next()
}

Thanks for help :P

Upvotes: 0

Views: 175

Answers (1)

MrLizzard
MrLizzard

Reputation: 178

You are trying to re-execute the res.status(500) twice.

In your try/catch clause, just add the return keyword like that:

try {
    if (await bcrypt.compare(body.password, user.password)) {
      body.password = user.password
    } else {
      const hashedPassword = await bcrypt.hash(body.password, 10)
      body.password = hashedPassword
    }
  } catch (e) {
    // I've added the return keyword here
    return res.status(500).send('Internal server error');
  }

Now, when your try/catch catch an error, the code not continue and stop here.

Upvotes: 1

Related Questions