【问题标题】:Q-promises and error handlingQ-promises 和错误处理
【发布时间】:2014-07-03 12:40:41
【问题描述】:

我正在尝试了解 Q Promises 以及如何处理从两个不同的 then 块引发的两个不同的错误。

这是我想“承诺”的功能:

router.post('/user', function(req, res) {
  var user = new User(req.body);
  User.findOne({ email: req.body.email }, function(error, foundUser) {
    if(foundUser) {
      res.send("Error: User with email " + foundUser.email + " already exists.", 409);
    } else {
      User.create(user, function(err, createdUser) {
        if (err) {
          res.send(err, 400);
        } else {
          res.json({ id: createdUser.id }, 201);
        }
      });
    }
  });  
});

它需要一些用户详细信息,并尝试使用相同的电子邮件创建一个新用户(如果尚不存在)。如果有,请发送 409。我还使用 400 处理正常的猫鼬错误。

我尝试使用 mongoose-q 将其转换过来,结果如下:

router.post('/user', function(req, res) {
  var user = new User(req.body);
  User.findOneQ({email : req.body.email})
  .then(function(existingUser) {
    if (existingUser) {
      res.send("Error: User with email " + existingUser.email + " already exists.", 409);
    } 
    return User.create(user);
  })
  .then(function(createdUser) { 
    res.json({ id: createdUser.id }, 201); 
  })
  .fail(function(err) { 
    res.send(err, 400)
  })
});

这是正确的吗?有没有办法将该现有用户检查推入失败块? IE。抛出一个Error,然后捕获它并处理它?

可能是这样的:

router.post('/user', function(req, res) {
  var user = new User(req.body);
  User.findOneQ({email : req.body.email})
  .then(function(existingUser) {
    if (existingUser) {
      throw new Error("Error: User with email " + existingUser.email + " already exists.");
    } 
    return User.create(user);
  })
  .then(function(createdUser) { 
    res.json({ id: createdUser.id }, 201); 
  })
  .fail(function(duplicateEmailError) {
    res.send(duplicateEmailError.message)
  })
  .fail(function(mongoError) { 
    res.send(mongoError, 400)
  })
});

【问题讨论】:

  • 您的原始代码有一个错误,它不会检查 error 是否在 .findOne 之后发生:
  • 如果你调用 .exec,Mongoose 已经返回了 Promise
  • 两位好,谢谢!

标签: node.js mongoose promise q


【解决方案1】:

我对 Q 的经验不够。不过,我可以用 bluebird 回答。

bluebird 支持 typed 捕获。这意味着您可以创建新的 Error 子类、抛出它们并相应地处理它们。

我在示例中使用了newerror 来简化错误子类的创建。

var newerror = require('newerror');

var DuplicateEmailError = newerror('DuplicateEmailError');

router.post('/user', function(req, res) {
    var user = new User(req.body);
    User.findOneAsync({ email: req.body.email }).then(function(existingUser) {
        if (existingUser) {
            throw new DuplicateEmailError('Error: User with email ' + existingUser.email + ' already exists.');
        }

        return User.createAsync(user);
    }).then(function(createdUser) {
        res.json({ id: createdUser.id }, 201);
    }).catch(DuplicateEmailError, function(err) {
        res.send(err.message, 409);
    }).catch(function(err) {
        res.send(err.message, 500);
    });
});

【讨论】:

  • 顺便说一句 DuplicateEmailError 不会有任何 .message
  • @Esailija 确实如此。修复它:)
  • Q 不支持键入的 catch,您必须在 .catch 中执行 if(err instanceof){ 检查
  • 那种烂。嗯,我应该使用哪些其他方法来处理错误?
  • @DominicBou-Samra 只是放弃 Q 并使用 bluebird,有什么问题? :D
猜你喜欢
  • 2016-11-05
  • 1970-01-01
  • 2014-12-01
  • 2017-01-11
  • 2019-01-15
  • 1970-01-01
  • 2014-06-21
  • 2016-06-08
  • 2018-10-26
相关资源
最近更新 更多