在异步中捕获错误等待

时间:2020-05-27 12:30:52

标签: javascript

我具有以下功能:

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()的调用)是否正确?我将如何独立捕获此错误?我需要在trycatch语句中添加trycatch吗?

2 个答案:

答案 0 :(得分:0)

捕获是否会触发块中的所有错误是否正确 包括调用Role.find({name:{$ in:req.body.roles }})。exec()?

是的,如果mongoose引发错误,则该错误将由它遇到的第一个catch块捕获,在您的情况下,该块是catch函数中的signup

我将如何独立捕获此错误?

您可以将包含findOne函数调用的语句包装到另一个try-catch块中

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

catch块将仅捕获以下语句执行期间引发的错误

await Role.findOne({name: 'user'}).exec();

错误由它们在调用堆栈中遇到的第一个catch块捕获。如果在try-catch函数调用周围有嵌套的findOne块,则在执行该语句期间引发的任何错误都将被嵌套的catch块捕获,而不是外部的{{1} }块。

如果您从嵌套的catch块抛出错误,则该错误将被catch函数中的外部catch块捕获。

答案 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