如何从异步函数中抛出异常

新手上路,请多包涵

我有一个异步函数,我希望它在失败时抛出异常。然而,似乎有些事情阻止了这一点:

通过省略 try catch 块,我希望抛出一个我想在函数外部处理的异常。

我得到的实际结果有些混乱:

(node:10636) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): E11000 duplicate key error index.

(node:10636) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

 async f(obj) {
    await db.collection('...').save(obj);
}

当我尝试捕获异常并抛出其他东西时,我得到了相同的结果:

 async f(obj) {
    try {
        await db.collection('...').save(obj);
    } catch(e) {
        throw e.message;
    }
}

该函数是从 try 块中调用的,所以看不出这是一个 Unhandled Promise。

我正在尝试使用 f 作为另一个函数的参数:

 g(obj, handler) {
    try {
        handler(obj);
    } catch(e);
        ...
    }
}

g(objToSave, f);

原文由 user1063963 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 817
2 个回答

最终,您要做的是在同步函数 f 中调用异步函数 g ,这是行不通的(这相当于能够打开一个异步函数转换为同步函数)。

相反, g 也必须是 async ,或者它应该正确处理 f 返回的承诺。但是, 在此评论中, 您声明由 f 表示的函数可能并不总是返回承诺,在这种情况下,前一个选项最容易实现:

 async g(obj, handler) {
  return await handler(obj);
}

如果 handler 不返回承诺,而只是一个值(记录 在此处),这也将起作用。

调用 g (再次)需要异步函数或代码来处理其返回的承诺:

 g(objToSave, f).then(...).catch(...)

原文由 robertklep 发布,翻译遵循 CC BY-SA 3.0 许可协议

async f(obj) {
    try {
        await db.collection('...').save(obj);
    } catch(e) {
        throw e.message;
    }
}

该函数是从 try 块中调用的,所以看不出这是一个 Unhandled Promise。

这里未处理的是拒绝 f() 函数返回的承诺,而不是 .save() 方法。所以这不会导致那个问题:

 async f(obj) {
    try {
        await db.collection('...').save(obj);
    } catch(e) {
        console.error(e.message);
    }
}

在异步函数中抛出异常总是会拒绝 该函数 返回的 承诺

要捕获异常,您必须在另一个异步函数中执行此操作:

 try {
    asyncFunc();
} catch (err) {
    // you have the error here
}

或者您可以显式添加拒绝处理程序:

 asyncFunc().catch(err => {
    // you have the error here
});

如果您正在捕获异常并抛出另一个异常,那么您会遇到同样的问题,只是在不同的函数中。

您必须添加一个承诺拒绝处理程序并且不抛出异常或在那里返回一个被拒绝的承诺 - 或者在另一个处理异常的异步函数中运行该函数而不是重新抛出相同或新的异常。

总结一下: 每个 async 函数都会返回一个承诺。每个承诺都需要有一个拒绝处理程序。

使用两个函数添加拒绝处理程序 .then().catch()try { await asyncFunction(); } catch (err) { ... }

当您有一个没有拒绝处理程序的承诺拒绝时,您将在旧版本的 Node 中收到警告,在新版本的 Node 中收到致命错误 - 请参阅此答案以获取更多详细信息:

原文由 rsp 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题