【问题标题】:Handling errors with Javascript and Node.js (then/catch)使用 Javascript 和 Node.js (then/catch) 处理错误
【发布时间】:2020-01-28 15:02:52
【问题描述】:

假设我在 routes.js 文件中有这个伪代码:

var pkg = require('random-package');

app.post('/aroute', function(req, res) {
    pkg.impl_func(data, function (err, result) {
        myFunction(entity).then(user=>{
            //DO_STUFF_HERE
            res.render('page.ejs');
        }).catch(err => {
            console.log(err);
            res.render('error.ejs');
        });
    });
});

function myFunction(username) {
   //.....
}

我使用的 pkg 是在 npmjs 网站上找到的。 myFunction() 永远是我的职责。

在我的代码中,您可以看到当myFunction() 失败时,我已经实现了 then/catch 语句。 因此,当这种情况发生时,error.ejs 会被渲染。

但是当 npm 包失败时会发生什么? 在终端中,我收到错误消息,但服务器端没有错误处理。 这意味着,当它失败时,用户将不会收到error.ejs 的通知,很明显,因为我的代码中省略了此功能。

但是当 pkg 失败时,error.ejs 的渲染方法是什么?

既然我已经在下面使用.then()/.catch() 技术,我也可以在上面做吗? 换句话说,我可以嵌套.then()/.catch() 语句吗? 我可以将外部代码包围到try/catch(同时内部还有try/catch)吗?

【问题讨论】:

    标签: javascript node.js express error-handling try-catch


    【解决方案1】:

    您可以使用简单的try/catch 将其全部包装起来,并将error.js 也呈现在该捕获中。

    至于嵌套try/catch...是的,你可以。然而,在这种情况下,promise catch() 与基本的 try/catch 略有不同

    app.post('/aroute', function(req, res) {
    
          try {
            pkg.impl_func(data, function(err, result) {
              myFunction(entity).then(user => {
                //DO_STUFF_HERE
                res.render('page.ejs');
              }).catch(err => {
                console.log(err);
                res.render('error.ejs');
              });
            });
    
          } catch (e) {
            res.render('error.ejs');
          }
        });
    });
    

    【讨论】:

    • 谢谢,但我试过了,但没有用。错误被抛出 - 在终端中很明显,但没有重定向到“error.ejs”。 (顺便说一句,在您的代码中,您还有一对 '});'它是必需的。)
    【解决方案2】:

    pkg.impl_func() 似乎实现了典型的 Node.js 回调接口(即,它在发生错误时返回错误作为第一个参数,如果没有错误,则返回 null)。您可以简单地检查错误是否存在并在出现时呈现您的error.ejs

    app.post('/aroute', function(req, res) {
      pkg.impl_func(data, function (err, result) {
        if (err) {
          res.render('error.ejs');
        } else {
          myFunction(entity).then(user=>{
            //DO_STUFF_HERE
            res.render('page.ejs');
          }).catch(err => {
            console.log(err);
            res.render('error.ejs');
          });
        }
      });
    });
    

    或者,您可以使用util.promisify()pkg.impl_func() 转换为异步函数。然后你可以在async 函数中使用promise.catch()try-catch 来简化语法:

    const util = require('util')
    const impl_func_async = util.promisify(pkg.impl_func)
    
    // traditional promises:
    app.post('/aroute', (req, res) => {
      impl_func_async(data).then(result =>
        return myFunction(entity)
      }).then(user => {
        // DO_STUFF_HERE
        res.render('page.ejs')
      }).catch(e => {
        // Will catch thrown errors from impl_func_async and myFunction
        console.log(e)
        res.render('error.ejs')
      })
    })
    
    // async-await:
    app.post('/aroute', async (req, res) => {
      try {
        const result = await impl_func_async(data)
        const user = await myFunction(entity)
        // DO_STUFF_HERE
        res.render('page.ejs')
      } catch (e) {
        // Will catch thrown errors from impl_func_async and myFunction
        console.log(e)
        res.render('error.ejs')
      }
    })
    

    【讨论】:

      猜你喜欢
      • 2023-01-10
      • 2018-10-29
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-02
      • 1970-01-01
      相关资源
      最近更新 更多