【问题标题】:Crashing the application from within a Q promise instead of propagate a rejection through a chain of promises?从 Q 承诺中崩溃应用程序,而不是通过一系列承诺传播拒绝?
【发布时间】:2015-04-27 00:48:10
【问题描述】:

所以基本上问题在于 Q 吞下了我的异常,这些异常并不意味着拒绝承诺,而是尽早使应用​​程序崩溃,以便我知道究竟是什么被破坏了。

我知道我可以(并且可能应该)在链的末端使用done 方法,但是跟踪链的末端真的很痛苦。它并没有太大帮助,因为它不会阻止 Q 捕获它,并且一旦缓存异常就会失去它的堆栈跟踪。

有没有办法在抛出异常时尽早崩溃,而不是将拒绝传播到链上,希望在它结束时完成?

【问题讨论】:

  • 如果您有永远不应该处理的异常,为什么不明确终止?
  • @SLaks,这就是问题所在,我希望我可以显式终止,但是从 Promise 处理程序执行上下文中抛出所有异常并且无法显式终止,或者至少我不知道怎么做
  • 所以你抱怨是因为 promise 的一个主要特性——“throw-safety”?然后,停止使用 Promise。这就是他们应该工作的方式。
  • 没错。吞下所有异常是一种不好的做法。为开发人员决定什么对他们来说是正确的而不给他们选择是另一种不好的做法。将异常处理与处理有效数据分开是防止 Promise 成为真正的函子和 monad 的原因。所以,是的,你所说的投掷安全只是糟糕设计的一个例子。我确实需要找到或开发其他以正确方式做事的东西。
  • @AlekseyBykov 我谦虚地不同意,您的库代码决定 my 应用程序如果您的库失败,它应该终止是一个 巨大 违反分离担忧 - 您的代码没有更广泛的视野,不应该做出这些决定。这与同步代码完全一样。请read this thread讨论该主题。

标签: javascript promise q


【解决方案1】:

好的,所以我的 Q 的 PR 刚刚合并,你现在可以这样做了:

process.on("unhandledRejection", function(err, promise){
    throw err; // terminate with error if a `.catch` is not attached
});

这将导致进程在未明确处理异常时退出(通过catch)。这结束了关于 Promise 的长期调试问题。 .done 的日子已经一去不复返了。

请确保获得 6 分钟前发布的 Q 1.30:D

【讨论】:

    【解决方案2】:

    您正在寻找process.exit(1)(或任何其他退出代码),它将立即终止进程而不会引发异常。

    【讨论】:

    • 来自浏览器,不能终止
    • @AlekseyBykov:那你想做什么?
    • 我希望浏览器使用其标准机制报告未捕获的异常(通常是带有堆栈跟踪的转储到控制台)
    • 在我自己的代码中本来是一个选项,但我有一个只是抛出的黑盒子的代码,我不能把 console.error 放进去,当然我可以把它包装在我自己的里面try/catch 但这对于一些本来可以在没有任何额外努力的情况下工作的东西来说很麻烦,我明白你的意思,我需要一个直接的解决方案,我不是在寻找解决方法
    • 并且不存在直接的解决方案,所以我的运气不好:github.com/kriskowal/q/issues/684
    【解决方案3】:

    实现此目的的一种方法是推迟 Promise 回调的实际执行。这将强制函数进入事件队列,调用函数不会捕捉到这个错误。

    一个例子:

    try {
        setTimeout(function () {
            throw new Error('Not caught');
        });
    } catch (e) {
        console.log(e);
    }
    

    但是,我不确定这是否比仅使用 .done 好得多。

    【讨论】:

      猜你喜欢
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      • 1970-01-01
      • 2016-09-02
      • 1970-01-01
      • 2019-11-25
      • 2018-05-09
      相关资源
      最近更新 更多