在承诺之外抛出错误

时间:2017-09-11 08:53:20

标签: javascript json node.js error-handling promise

我有一个函数来登录应该返回JSON的用户。

const username = req.body.username;
const password = req.body.password;

if (!username) {
  throw new Error('Missing username');
}

if (!password) {
  throw new Error('Missing password');
}

User.findOne({ username, password }).then(user => {
  res.json({ user });
}).catch(err => {
  res.json({ err });
});

但是在JSON中不会返回缺少用户名或缺少密码的错误。

我可以将其改为

const username = req.body.username;
const password = req.body.password;

if (!username) {
  res.json({ err: 'Missing username' });
}

if (!password) {
  res.json({ err: 'Missing password' });
}

User.findOne({ username, password }).then(user => {
  res.json({ user });
}).catch(err => {
  res.json({ err });
});

但似乎有点多余。

是否有正确的方法将其封装在承诺中?

4 个答案:

答案 0 :(得分:1)

在您的第一个解决方案中,抛出的错误将无法处理,因为您将它们抛出承诺链并且没有try/catch阻止。在第二个解决方案中,您可能会收到cannot send headers after they sent错误,因为响应可能会被发送两次(username丢失且password丢失)。

所以这里可能的解决方案之一是创建一个promise链(使用Promise.resolve())并在此验证参数:

function validateParams() {
  const username = req.body.username;
  const password = req.body.password;

  if (!username) {
    throw new Error('Missing username');
  }
  if (!password) {
    throw new Error('Missing password');
  }
  return { username, password };
}

Promise
  .resolve()
  .then(validateParams)
  .then(filter => User.findOne(filter))
  .then(user => res.json(user))
  .catch(err => res.json(err));

答案 1 :(得分:0)

显而易见的方法是将它们封装在一个承诺中,以启动你的承诺链(User.findOne位于第一个then - 块内) - 这样你当前的错误处理程序就会捕获它们细

答案 2 :(得分:0)

您可以将您的函数包装在一个承诺中并有效地处理它

function getRes(){  
    return new Promise(function(resolve, reject){
        const username = req.body.username;
        const password = req.body.password;

        if (!username) {
          reject(new Error('Missing username'));
        }

        if (!password) {
          reject(new Error('Missing password'));
        }

        resolve(User.findOne({ username, password }));
    });
}


getRes().then(function(result){
    res.json(result);
}).catch(function(err){
    res.json(err);
})

答案 3 :(得分:0)

我从@alexmac中获取示例并使用es6异步功能:

function validateParams() {
  const username = req.body.username;
  const password = req.body.password;

  if (!username) {
    throw new Error('Missing username');
  }
  if (!password) {
    throw new Error('Missing password');
  }
  return { username, password };
}

async function resolver() {
    try {
        await resolve()
        let filter = validateParams()
        let user = await User.findOne(filter)
        await res.json(user)
    } catch (e) {
        await res.json(e)
    }
 }

使用if而不是throw看起来更优雅:

async function(req, res) {
    const password = req.body.password
    const username = req.body.username
    let c = !password ? 'missing password' : 
                !username ? 'missing username' : null
    if (!c) {
       c = await User.findOne({ username, password })
    }
    await res.json(c)
}