Node.js Q-承诺与错误处理

Node.js Q-承诺与错误处理,node.js,mongoose,promise,q,Node.js,Mongoose,Promise,Q,我试图理解Q承诺,以及如何处理从两个不同then块抛出的两个不同错误 以下是我想“承诺”的功能: 它会获取一些用户详细信息,并尝试创建一个新用户(如果该用户还没有使用相同的电子邮件)。如果有,发送409。我也用400来处理正常的猫鼬错误 我曾尝试使用mongoose-q将其转换,结果是: router.post('/user', function(req, res) { var user = new User(req.body); User.findOneQ({email : req.b

我试图理解Q承诺,以及如何处理从两个不同then块抛出的两个不同错误

以下是我想“承诺”的功能:

它会获取一些用户详细信息,并尝试创建一个新用户(如果该用户还没有使用相同的电子邮件)。如果有,发送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)
  })
});
这是正确的吗?是否存在将现有用户检查推入失败块的方法?也就是说,抛出一个错误,然后抓住它并处理它

也许是这样的:

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)
  })
});

我对Q没有足够的经验。但是,我可以用蓝鸟来回答

支持类型化捕获。这意味着您可以创建新的错误子类,抛出它们,并相应地处理它们

在我的示例中,我使用了
newerror
来简化Error子类的创建

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);
    });
});

您的原始代码有一个bug,它不会检查之后是否发生了
错误。findOne:Mongoose已经在您呼叫
时返回了承诺。exec
很好,谢谢!顺便说一句,DuplicateEmailError不会有任何错误。message@Esailija的确修正了:)Q不支持键入捕获,你必须在.catch中执行
if(err instanceof){
检查那种糟糕的方法。嗯,我应该使用什么方法来处理错误?@DominicBou Samra删除Q并使用bluebird,有什么问题吗?:d
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);
    });
});