未处理的承诺拒绝-错误:发送标头后无法设置标头 [英] Unhandled promise rejection - Error: Can't set headers after they are sent

查看:101
本文介绍了未处理的承诺拒绝-错误:发送标头后无法设置标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Node的新手,我有一个简单的情况,我要发布到node/express应用程序上的端点.问题是我得到了:

I am new to node, and I have a simple situation, where I am posting to an endpoint on a node/express app. The issue is that I get:

POST /api/v2/user 500 25.378 ms - 54
(node:19024) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Can't set headers after they are sent.
(node:19024) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

我拥有的生成此代码的相关代码是:

The relevant code that I have which is generating this is:

router.post('/', (req, res, next) => {
  return authHelpers.createUser(req, res)
    .then((user) => {
      return localAuth.encodeToken(user[0]);
    })
    .then((token) => {
      res.status(201).json({
        status: 'success',
        message: 'User Created',
        token: token
      });
    })
    .catch((err) => {
      res.status(500).json({
        status: 'error'
      });
    });
});

然后:

function createUser(req, res) {
  return handleErrors(req)
    .then(() => {
      const salt = bcrypt.genSaltSync();
      const hash = bcrypt.hashSync(req.body.password, salt);
      return knex('users')
        .insert({
          email: req.body.email,
          first_name: req.body.first_name,
          last_name: req.body.last_name,
          username: req.body.username,
          password: hash
        })
        .returning('*');
    })
    .catch((err) => {
      res.status(410).json({
        status: err.message
      });
    });
}

function handleErrors(req) {
  return new Promise((resolve, reject) => {
    if (req.body.username.length < 6) {
      reject({
        message: 'Username must be longer than 6 characters'
      });
    } else if (req.body.password.length < 6) {
      reject({
        message: 'Password must be longer than 6 characters'
      });
    } else {
      resolve();
    }
  });
}

我确实知道,如果我专门删除 res.status(500).json({status:'error'}); ,那么该错误就会消失,但是我不确定是否那是正确的.

I do know that if I remove the res.status(500).json({status: 'error'}); specifically, then the error goes away, but I am not sure if that is proper.

关于我的错误到底是什么以及如何解决的任何线索吗?

Any clue to what exactly is my error and how to fix?

推荐答案

您尝试发送两次响应.首先发现错误

You are trying to send response twice. First when catching the error

  res.status(410).json({
    status: err.message
  });

然后在捕获之后,promise链将继续正常路线,直到:

And then after catch, promise chain continues the normal route until:

  return localAuth.encodeToken(user[0]);

由于用户未定义并引发异常而失败..因此,调用了错误处理程序,并且您尝试再次发送响应,但是失败了,因为它已经发送过一次

Which fails, because user is undefined and throws an exception.. so error handler is called and you are trying to send response again, but it fails because it has already been sent once

  res.status(500).json({
    status: 'error'
  });

控制台日志中上半部抛出了哪个错误,我敢肯定它是类似

console log which error was thrown in the last part, I'm pretty sure it is something like

  TypeError: Cannot read property '0' of undefined

这篇关于未处理的承诺拒绝-错误:发送标头后无法设置标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆