在 Node.js 中使用 async/await 正确处理错误

Posted

技术标签:

【中文标题】在 Node.js 中使用 async/await 正确处理错误【英文标题】:Proper error handling using async/await in Node.js 【发布时间】:2018-04-13 16:42:02 【问题描述】:

我的 Node.js express 应用中有以下代码:

router.route('/user')

   .post(async function(req, res) 
       if(req.body.password === req.body.passwordConfirm) 
           try 
               var response = await userManager.addUser(req.body);
               res.status(201).send();
            catch(err) 
               logger.error('POST /user failed with error: '+err);
               res.status(500).send(err:"something went wrong..");
           
        else 
           res.status(400).send(err:'passwords do not match');
       
   )

和用户管理器:

var userManager = function() 

    this.addUser = async function(userobject) 
        userobject.password_hash = await genHash(userobject.password_hash);
        var user = new User(userobject);
        return await user.save();
    ;

;

module.exports = userManager;

我的问题是:路由中的 try catch 块是否会捕获 addUser 中抛出的所有错误,还是只会捕获 user.save() 中抛出的错误>,因为那是返回的那个?

【问题讨论】:

addUser 是一个async function,因此从不抛出异常。它只会返回一个可能被拒绝的承诺。 只有当你await你的addUser打电话... 啊,不错,我忘了在那儿添加它! 【参考方案1】:

答案是肯定的,它会捕获try 块内和所有内部函数调用中的所有错误。

async/await 只是 Promise 的语法糖。因此,如果使用 Promise 可以实现某些事情,那么使用 async/await 也是可能的。

例如下面两个代码 sn-ps 是等价的:

使用承诺:

function bar() 
  return Promise.reject(new Error('Uh oh!'));


function foo() 
  return bar();


function main() 
  return foo().catch(e => 
    console.error(`Something went wrong: $e.message`);
  );


main();

使用async/await

async function bar() 
  throw new Error('Uh oh!');


async function foo() 
  await bar();


async function main() 
  try 
    await foo();
  
  catch(e) 
    console.error(`Something went wrong: $e.message`);
  


main();

事实上,您的代码将无法工作,因为您没有在 userManager.addUser 上使用 await

它还迫使您在父函数上使用async,这可能会破坏事情。检查 express 文档(或仅尝试是否有效)。

router.route('/user')

   .post(async function(req, res) 
       if(req.body.password === req.body.passwordConfirm) 
           try 
               var response = await userManager.addUser(req.body);
               res.status(201).send();
            catch(err) 
               logger.error('POST /user failed with error: '+err);
               res.status(500).send(err:"something went wrong..");
           
        else 
           res.status(400).send(err:'passwords do not match');
       
   )

【讨论】:

但是 OP 确实 try 块内使用 await 吗?!

以上是关于在 Node.js 中使用 async/await 正确处理错误的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 使用 async/await 和 mysql

Node.js 最佳实践异常处理——在 Async/Await 之后

Node.js 使用 async/await 读取文件

理解 Node JS 中的 async/await

node.js async/await 与 MySQL 一起使用

Node.js 7 的 async await 终于来了,不过怎么觉得没啥用