promise函数和Express中间件

时间:2017-10-20 11:00:51

标签: javascript node.js mongodb express mongoose

我正在尝试重构基于Express的简单API代码以使用promises而不是回调。我唯一的挑战是处理Mongoose验证错误(如果用户存在则进行示例测试)并将此错误抛出到中间件中。

我通过index.js上的中间件处理错误:

// Error handling middleware
app.use(function(err, req, res, next){
  res.status(422).send({error: err._message})
});

这是成功处理所有边缘情况的代码片段,除了现有的用户部分,其中错误被遗忘并且在响应中不可见:

router.post('/signup', function(req, res, next) {
  const email = req.body.email;
  const password = req.body.password;

  // Custom error
  if (!email || !password) {
    return res.status(422).send({ error: 'You must provide email and password'});
  }

  User.findOne({ email: email })
  .then(function(existingUser) {
    // If a user with email does exist, return an error
    if (existingUser) {
      // return res.status(422).send({ error: 'Email is in use' });
      throw new Error('User already exists!');
    }

    // If a user with email does NOT exist, create and save user record
    const user = new User({
      email: email,
      password: password
    });

    // save to database
    return user.save()
  })
  .then(function(user) {
    // Respond to request indicating the user was created
    res.json({ token: tokenForUser(user) });
  })
  .catch(next);

注意我注释掉了这段代码,因为它会引发错误"在发送标题后无法设置标题":

return res.status(422).send({ error: 'Email is in use' });

我的问题是:

  1. 我处理自定义验证错误的方式(例如测试电子邮件或密码字段是否为空)是正确的,还是有更好的方法,因为我没有通过错误中间件传递这些错误?
  2. 如何处理承诺中的错误?

1 个答案:

答案 0 :(得分:1)

您可以在新承诺中测试用户名和密码:

Promise.resolve().then(()=> {
  if (!email || !password) {
    throw new Error('You must provide email and password');
  }
  return User.findOne({ email: email })
})

then函数中抛出错误将停止执行并调用附加到promise的第一个catch。在您的情况下,next回调作为第一个参数的trowed错误。 Imo,你做得很好,它是在正确的中间件中表达应用程序发送客户端错误。