Q-promises 和错误处理

Posted

技术标签:

【中文标题】Q-promises 和错误处理【英文标题】:Q-promises and error handling 【发布时间】: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 两位好,谢谢! 【参考方案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

以上是关于Q-promises 和错误处理的主要内容,如果未能解决你的问题,请参考以下文章

转载 PHP的错误和异常处理

错误处理和时间函数

一些简单的错误处理函数

错误处理和时间函数

php错误处理

11. php的错误和异常处理