使用 async/await 时如何捕获错误

3
我有以下的函数:
exports.signup = async(req, res) => {
  console.log('signup');
  const user = new User({
      username: req.body.username,
      email: req.body.email,
      password: bcrypt.hashSync(req.body.password, 8)
  });

  try {
    if (await user.save()) {
        if (isNonEmptyArray(req.body.roles)) {
            // How do I catch this error? can be a role error or db error
            const roles = await Role.find({name: { $in: req.body.roles }}).exec()
            user.roles = roles.map(role => role._id);
            if (await user.save()) {
              success(res, 'Registered!');
            }
        } else {
            // How do I catch this error? can be a role error or a db error
            const role = await Role.findOne({name: 'user'}).exec();
            user.roles = [role._id];
            if (await user.save()) {
              success(res, 'Registered!');
            }
        }
    }
  } catch(error) {
    fail(res, {message: 'Database internal error occured.'});
  }
};

在此块中,包括对 await Role.find({name: { $in: req.body.roles }}).exec() 的调用,所有的错误都会触发 catch。我如何独立捕获此错误?需要在 try 语句中添加另一个 try-catch 块吗?


你刚才是不是试图在那里抛出一个异常,看看会发生什么? - Bergi
1个回答

0

就像你所说的,可以使用另一个try-catch块来区分你捕获的错误。

try {
   const role = await Role.findOne({name: 'user'}).exec();
} catch(err) {
  console.log(err);
}

另一个想法可能是使用 Promise 并在每个 .catch 段中捕获错误,例如

var query = Role.findOne({name: 'user'});
query.exec().then(function () {
    // handle success
}).catch(function (err) {
    // handle error
});

无论如何,在使用async/await和try-catch块时,有一些重要的功能需要记住,我将在此放置一篇文章的结论和链接,如果您感兴趣:

结论:

我们可以使用try...catch来处理同步代码。

我们可以使用try...catch(与异步函数结合使用)和.catch()方法来处理异步代码中的错误。

当在try块中返回一个promise时,如果想让try...catch块捕获错误,请确保等待它。

在包装错误并重新抛出时,请注意会丢失原始错误的堆栈跟踪。

来源:https://itnext.io/error-handling-with-async-await-in-js-26c3f20bc06a


1
这不是“另一个想法”,而是使用不同的语法完全相同的东西。 - Bergi
你是对的,我重新阅读了mongoose文档,发现.exec返回一个promise(不像简单查询),所以它是相同的,语法上的差异可能有助于引用文章中所说的原因。 - Consuelo Sanna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接