【问题标题】:Unhandled promise rejection Error: Can't set headers after they are sent未处理的承诺拒绝错误:发送后无法设置标头
【发布时间】:2017-09-08 00:56:57
【问题描述】:

我想做一个 if else 返回(用于 conrtole)但是:“UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:1):错误:发送后无法设置标头。 "

exports.delete = function (req, res) {
  Parking.findById(req.params.id).exec()
    .then(function (parking) {
      if (userController.ensureAuthorized(req, 'Director', parking.id)) {
        return parking;
      }
      return res.status(403).send({msg: 'unauthorized'});

    })
    .then(function (parking) {
      User.update().exec();
      return parking;
    })
    .then(function (parking) {
       return Parking.remove({_id: parking._id}).exec();
    })
    .then(function () {
      res.status(200).json({msg: 'Ok ! Parkink remove'});
    })
    .catch(function (err) {
      return res.status(400).send(err);
    });
};

【问题讨论】:

    标签: javascript node.js mongodb mongoose promise


    【解决方案1】:

    问题是在return res.status(403) 之后,承诺链不会自动停止。最终,它将命中res.status(200) 并导致错误。

    您可以稍微重写您的承诺链来防止这种情况发生。我不确定User.update().exec() 的目的是什么,但我假设您想调用它并等待它的承诺得到解决,然后再继续:

    exports.delete = function (req, res) {
      Parking.findById(req.params.id).exec()
        .then(function (parking) {
          if (userController.ensureAuthorized(req, 'Director', parking.id)) {
            return User.update(...).exec().then(function() {
              return Parking.remove({_id: parking._id}).exec();
            }).then(function() {
              return res.status(200).json({msg: 'Ok ! Parkink remove'});
            });
          } else {
            return res.status(403).send({msg: 'unauthorized'});
          }
        }).catch(function (err) {
          return res.status(400).send(err);
        });
    };
    

    【讨论】:

    • 我会说不要使用arrow function,因为我们不知道node OP 使用的是哪个版本。
    • @Kymz 查看我的编辑,我在承诺链中加入了对User.update() 的调用。
    • @robertklep 并不完美,但我可以保留停车位(通过 id 查找)直到最后?只是现在(如果我想要 res.send (parking.name))
    • @Kymz 是的,parking 将在整个承诺链范围内(但是,它不会catch 处理程序中可用,但你是反正不在那里使用它)
    • 再次感谢您,真的!
    【解决方案2】:

    嗯,breaking the promise chain 没有标准的方式。

    所以我要抛出一个错误来打破链条,然后处理那个自定义抛出的错误:

    exports.delete = function (req, res) {
      Parking.findById(req.params.id).exec()
        .then(function (parking) {
          if (userController.ensureAuthorized(req, 'Director', parking.id)) {
            return parking;
          }
          else {
            res.status(403).send({msg: 'unauthorized'});
            throw new Error('BREAK_CHAIN'); //      <-- intentionally throw error
          }
        })
        .then(function (parking) {
          User.update().exec();
          return parking;
        })
        .then(function (parking) {
           return Parking.remove({_id: parking._id}).exec();
        })
        .then(function () {
          res.status(200).json({msg: 'Ok ! Parkink remove'});
        })
        .catch(function (err) {
            if(err.message != 'BREAK_CHAIN')    //      <-- handle if error was intentionally thrown
                return res.status(400).send(err);
        });
    };
    

    【讨论】:

      【解决方案3】:

      作为其他答案的补充,我建议:

      1) 将事物分解成小部分

      2)按预期使用throw,引发非授权错误

      function update (parking) {
        User.update().exec()
          .then(function () {
            Parking.remove({_id: parking._id}).exec();
          });
      }
      
      exports.delete = function (req, res) {
        // auth needs req so we put it in scope
        var auth = function (parking) {
          if (!userController.ensureAuthorized(req, 'Director', parking.id)) {
            throw(new Error(403));
          }
          return parking;
        }
      
        Parking.findById(req.params.id).exec()
          .then(auth)
          .then(update)
          .then(function () {
            res.status(200).json({msg: 'Ok ! Parkink remove'});
          })
          .catch(function (err) {
            if (err.message === 403) {
              return res.status(403).send({msg: 'unauthorized'});
            }
            return res.status(400).send(err);
          });
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-20
        • 1970-01-01
        • 1970-01-01
        • 2018-01-04
        • 1970-01-01
        • 2021-06-03
        • 2016-09-02
        • 2018-11-07
        相关资源
        最近更新 更多