【问题标题】:How can I catch errors here?我怎样才能在这里发现错误?
【发布时间】:2018-05-06 19:26:56
【问题描述】:

我有路由器和两个从数据库中获取的 acync。在这里捕获错误的正确方法是什么?

router.get('/restaurant/:id', async (req, res, next) => {
    var current_restaurant = await Restaurant.findOne({restaurantId: req.params.id}).exec();
    var products = await Product.find({restaurant: req.params.id}).exec();

    res.render('restaurant', {  
        user: req.user,
        csrfToken: req.csrfToken(),
        current_restaurant: current_restaurant,
        products: products
    });
});

【问题讨论】:

  • try/catch 是在使用 async/await 时捕获错误的方法 - 大多数体面的文档/教程都会显示这一点,例如 MDN code
  • 我知道最后是投票,但是人们可以在接近投票的情况下表现出一点克制吗?我最近看到的很多问题都无缘无故地投票(或者至少不是他们选择的问题)
  • 当然不是太宽泛,但考虑到所有使用 async/await 进行错误处理的示例,OP 至少可以证明他/她知道 try/catch。这使得这个问题没有得到很好的研究。如果该问题包含在问题中,则可能是重复的。

标签: javascript node.js express mongoose async-await


【解决方案1】:

如果您要使用 await,那么您将使用 try/catch 来捕获对您正在等待的任何一个 Promise 的拒绝:

router.get('/restaurant/:id', async (req, res, next) => {
    try {
        let current_restaurant = await Restaurant.findOne({restaurantId: req.params.id}).exec();
        let products = await Product.find({restaurant: req.params.id}).exec();
        res.render('restaurant', {  
            user: req.user,
            csrfToken: req.csrfToken(),
            current_restaurant: current_restaurant,
            products: products
        });
     } catch(e) {
         // do whatever you want 
         console.log(e);
         res.sendStatus(500);
     }
});

您可以将其与使用 .then() 的常规 Promise 编程进行比较:

router.get('/restaurant/:id', async (req, res, next) => {
    Promise.all([
        Restaurant.findOne({restaurantId: req.params.id}).exec(),
        Product.find({restaurant: req.params.id}).exec()
    ]).then([current_restaurant, products] => {
        res.render('restaurant', {  
            user: req.user,
            csrfToken: req.csrfToken(),
            current_restaurant: current_restaurant,
            products: products
        });
    }).catch(e => {
        // add your desired error handling here
        console.log(e);
        res.sendStatus(500);
    });
});

由于您的两个数据库请求彼此独立,因此第二个版本允许并行数据库查询,并且实际上可能运行得稍微快一些(取决于您的数据库)。

【讨论】:

    【解决方案2】:

    要么:

    try {
        var current_restaurant = await Restaurant.findOne({restaurantId: req.params.id}).exec();
        var products = await Product.find({restaurant: req.params.id}).exec();
    
        res.render('restaurant', {  
            user: req.user,
            csrfToken: req.csrfToken(),
            current_restaurant: current_restaurant,
            products: products
        });
    } catch (err) {
        // Handle your errors here...
    }
    

    这是您的典型模式。根据您是否可以恢复并继续渲染(使用默认值或其他内容),您可能只想将 await 调用包含在 try 块中(并在 try 块之前声明变量)。

    否则,您正在等待 Promise,因此您仍然可以使用 Promise .catch 方法,如果您觉得这样更简洁。

    var current_restaurant = await Restaurant.findOne({restaurantId: req.params.id}).exec()
        .catch(err => { /* handle error here*/ });
    var products = await Product.find({restaurant: req.params.id}).exec()
        .catch(err => { /* handle error here*/ });
    

    但是,只有当您仍然可以在您的 catch 代码中返回一些有效的东西(例如,某种默认值或回退值)时,这种模式才会有用。如果您需要在发生错误时退出整个事情,这对您不起作用,您应该改用前面提到的try/catch 模式。

    【讨论】:

      猜你喜欢
      • 2022-10-18
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      • 2014-03-05
      • 2022-01-22
      • 1970-01-01
      • 2017-05-25
      • 2021-10-01
      相关资源
      最近更新 更多