Проблема с ERR_HTTP_HEADERS_SENT и предупреждением об обещании

#javascript #node.js #express

#javascript #node.js #выразить

Вопрос:

У меня есть два предупреждения о приведенном ниже коде, и я не знаю, как решить эти проблемы. Первая проблема — это предупреждение: Warning: a promise was created in a handler и проблема после того, как прокомментировал мою строку кода.

и вторая ошибка:

Unhandled rejection Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client . Я прокомментировал код этой строкой

 // Login Action
exports.login = (req, res) => {
  function getTodayDate() {
    const today = new Date();
    return today;
  }

  function getToken(userId) {
    const token = jwt.sign(
      {
        id: userId,
      },
      env.SECRET_KEY,
      {
        expiresIn: '60min',
      },
    );
    return token;
  }

  User.findOne({
    where: {
      login: req.body.login,
    },
  })
    .then(isUser => {
      if (isUser) {
        if (bcrypt.compareSync(req.body.password, isUser.password)) {
          User.update( // <- this is started my problem?
            {
              last_present_logged: getTodayDate(),
            },
            { where: { login: req.body.login } },
          ).then(() =>
            res.status(200).json({
              success: true,
              token: getToken(isUser.id),
            }),
          );
        }
        User.update(
          {
            last_failed_logged: getTodayDate(),
          },
          { where: { login: req.body.login } },
        ).then(() => {
          res.status(200).json({ // <- this is my red error!
            error: 'Auth failed. The password is incorrect.',
            success: false,
          });
        });
      } else {
        res
          .status(200)
          .json({ error: 'Auth failed. User does not exist', success: false });
      }
    })
    .catch(() => {
      /* just ignore */
    });
};
  

как я могу решить эти проблемы?
как я могу решить эти проблемы?

Ответ №1:

Проблема в том, что вы дважды завершаете запрос, если bcrypt.compareSync() он соответствует действительности. Если вы сделаете это, вы получите Headers already sent

Что вам нужно сделать, это либо return внутри if , либо обернуть следующий User.update внутри else

  User.findOne({
    where: {
      login: req.body.login,
    },
  })
    .then(isUser => {
      if (isUser) {
        if (bcrypt.compareSync(req.body.password, isUser.password)) {
          return User.update( // <- this is started my problem?
            {
              last_present_logged: getTodayDate(),
            },
            { where: { login: req.body.login } },
          ).then(() =>
            res.status(200).json({
              success: true,
              token: getToken(isUser.id),
            }),
          );
        }

        // Now this code won't be executed if `compareSync` is truthy.
        // Issue a return, so in case of failure, it goes to the .catch
        // avoiding UnhandledPromiseRejection warning
        return User.update(
          {
            last_failed_logged: getTodayDate(),
          },
          { where: { login: req.body.login } },
        ).then(() => {
          res.status(200).json({ // <- this is my red error!
            error: 'Auth failed. The password is incorrect.',
            success: false,
          });
        });
      } else {
        res
          .status(200)
          .json({ error: 'Auth failed. User does not exist', success: false });
      }
    })
    .catch(() => {
      /* just ignore */
      // Please, don't ignore, end the request here
      res.status(500).json({ error: 'Internal server error });
    });