【问题标题】:how to properly throw an error if promise is rejected? (UnhandledPromiseRejectionWarning)如果 promise 被拒绝,如何正确抛出错误? (UnhandledPromiseRejectionWarning)
【发布时间】:2018-01-27 23:43:50
【问题描述】:

我有一个承诺,如果承诺被拒绝,我希望抛出一个异常。我试过这个:

var p = new Promise( (resolve, reject) => {
  reject ("Error!");
} );

p.then(value => {console.log(value);});

但我收到了弃用警告:

(node:44056) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error!
(node:44056) 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.

如果 promise 被拒绝,抛出错误的正确方法是什么(以便程序以堆栈跟踪终止)?

我已经尝试在 catch 子句中插入一个 throw 语句,但这又像以前一样产生了 DeprecationWarning。事实上(经过一些阅读)我知道抛出一个 catch 会产生另一个对拒绝回调的调用。

【问题讨论】:

  • "我想抛出一个异常" - 什么?为什么?去哪里?你想在哪里抓到它?
  • 我想终止程序并向用户显示堆栈跟踪...作为未来的行为。

标签: javascript es6-promise


【解决方案1】:

您将收到 DeprecationWarning,因为在解决承诺时添加 catch block 将是强制性的。

您可以从 catch 块内部抛出错误,这样您的程序将被错误的堆栈跟踪终止,例如:

p.then( value => console.log(value) ).catch( e => { throw e });

否则,您可以在不终止进程的情况下捕获错误并做一些事情,例如:

p.then( value => console.log(value) ).catch( e => { console.log('got an error, but the process is not terminated.') });

【讨论】:

  • 第一个(这是我想要的)似乎等同于不放置 catch 子句:它引发了 DeprecationWarning
  • 是的,你是对的,我相信@robertklep 已经回答了这个问题。
【解决方案2】:

您可以捕获 unhandledRejection 事件以记录堆栈跟踪,前提是您使用正确的 Error 拒绝:

var p = new Promise( (resolve, reject) => {
  reject( Error("Error!") );
} );

p.then(value => {console.log(value);});

process.on('unhandledRejection', e => {
  console.error(e);
});

【讨论】:

  • 把 process.on 放在你的脚本里面解决问题
【解决方案3】:

...如果 promise 被拒绝,程序会以堆栈跟踪终止?

正如“弃用”警告告诉你的那样,这正是未处理的承诺拒绝将来会做的事情。见these pull requests 表示他们打算做什么,以及the general discussion

现在,您可以收听unhandledRejection 事件来执行此操作:

process.on('unhandledRejection', err => {
  console.error(err); // or err.stack and err.message or whatever you want
  process.exit(1);
});

【讨论】:

  • 所以我可以放心地忽略警告并保持代码不变?这实际上是获得我需要的东西的正确方法。
  • @EmanuelePaolini 弃用警告,是的。未处理的拒绝警告,不 - 您应该编写不处理错误的代码。最好写p.then(console.log, console.error);,它通过记录错误来处理错误(然后像往常一样终止)。
  • 使用 node.js(来自 python)的第一天,所以我可能是错的。但只有当我能够处理它们时,我才会捕获异常。如果我有意外的异常(可能是编程错误),我认为最好的办法是让用户自行处理......我认为没有理由记录异常,因为它无论如何都会被记录。
  • @EmanuelePaolini 问题是 Promises(和一般的 JS)不能轻易区分(意外的)程序员和(预期的)操作错误。没有条件 catch 子句(如 Python 中的 except X:),您始终需要捕获所有错误并明确区分它们。我的猜测是,没有这种“留给用户”的功能是 Node.js 主要是为服务器应用程序而不是交互式应用程序构建的。与异常不同的承诺拒绝工作是 imo 一个不幸的设计错误,但现在很难改变它。
猜你喜欢
  • 2021-11-08
  • 1970-01-01
  • 2015-04-29
  • 2018-04-12
  • 1970-01-01
  • 2022-01-18
  • 2020-08-01
  • 1970-01-01
  • 2014-09-14
相关资源
最近更新 更多