【问题标题】:How do I work with the Bluebird error handler?如何使用 Bluebird 错误处理程序?
【发布时间】:2014-03-17 17:15:34
【问题描述】:

简介

这个问题旨在最终解决我在开发 Bluebird 时遇到的问题。但是,我也在利用这个机会澄清一些事情,所以会有一些附带问题。对于您在阅读即将到来的故事时可能遇到的任何困惑或无聊感,我也提前道歉。


问题

据我了解,Bluebird 会根据以下策略智能地捕捉被忽略的拒绝:

Bluebird 默认采用的第二种方法是,如果在第二轮开始时拒绝未处理,则调用已注册的处理程序。 -- Bluebird Readme # Error Handling

现在是第一个侧面问题:“第二轮的开始”是什么意思?

稍后在同一部分中,记录了以下内容:

当然,这并不完美,如果您的代码出于某种原因需要在某个 Promise 挂起一段时间后突然介入并将错误处理程序附加到某个 Promise 上,那么您会看到烦人的消息。在这种情况下,您可以使用 .done() 方法来表示应该抛出任何挂起的异常。 -- Bluebird Readme # Error Handling

现在,我相信我遇到了上述情况,我的用例如下:

  • 我调用一个函数,该函数将为我提供我附加.catch() 的承诺:

    lib.loadUrls()
    .catch(function(e){console.log(e);});
    
  • 在内部,该函数从 URL1 加载内容,并根据内容依次从 URL2 加载内容:

    lib.loadUrls =
      return this.loadUrl1()
      .then(this.loadUrl2.bind(this))
    
  • 如果此链中的第二个 Promise 被拒绝,则错误将由 catch first 处理,然后由 Bluebirds Possibly unhandled error 处理程序处理。

最后一个行为是不需要的,我不知道为什么会这样。所以问题二可能是:为什么尽管附加并执行了错误处理程序,Bluebird 仍会考虑错误被“未处理”的可能性?

我在想,当拒绝传播到.catch() 时,显然承诺“已经存在了一段时间”。在这种情况下,我应该通过“使用.done()”来解决它(根据引用的文档)。

现在,我已经尝试了几件事,但我不太清楚如何在这种情况下“使用 .done”。 (.done() 返回 undefined 并没有帮助,阻止我 .finally-ing。)

所以这引入了我的第三个和第四个问题:我如何在这种情况下使用.done()以及我如何明确地结束一个承诺链,但仍然附加一个@ 987654337@

编辑 1:我创建了一些 JSFiddles 来重现错误:

编辑 2: 开发者 fixed 错误。

【问题讨论】:

  • 请显示完整的被调用者和调用者函数体
  • 我创建了一个JSFiddle 来重现该错误。打开页面时,您会看到错误由错误处理程序处理,然后由未处理的错误处理程序处理。

标签: javascript node.js promise bluebird


【解决方案1】:

这确实只是 bluebird 中的一个回归错误,现已修复。

关于需要使用.done() 的那一点几乎是理论上的,在实践中您不会在需要附加错误处理程序的情况下运行,这种情况会导致报告误报。

【讨论】:

    【解决方案2】:

    这很可能是 Bluebird 错误,因为不应报告 handled 错误(假设您正确处理了 loadUrls 正文中的承诺)。因此,您可能应该将其报告给 Bluebird 问题跟踪器。

    关于done,当您只处理解析值时,最好使用纯访问函数而不是thencatch

    最好将done 视为首选函数并仅在您确实需要转换为其他promise 时使用thencatch,通过这种方法您也不需要依赖错误的错误监控(最好将其完全关闭)。

    在您的情况下,done 应用作:

    lib.loadUrls().done(); // eventual error will be thrown
    

    如果出于某种原因您想专门处理错误(例如,在运行的服务器中您不希望它抛出),请执行以下操作:

    lib.loadUrls().done(null, function (error) {
      // handle error
    });
    

    编辑:

    刚刚注意到,您仍然希望处理 lib.loadUrls().catch(..)finally 返回的承诺。在这种情况下,done 不是解决方案。 done 只能用作最终调用,但您可以将其与 finally 组合使用,如下所示:

    lib.loadUrls().finally(function () {
      // cleanup
    }).done();
    

    【讨论】:

    • 谢谢! donefinally 现在对我来说很清楚了。你可能是对的,它是一个错误,就像我做的那样:lib.loadUrls().catch(handleError).done()...handleError 被调用。 done 没有抛出异常,然后仍然 Bluebird 之后将其处理为“可能未处理”。你能否为我澄清最后一件事。 “第二回合的开始”何时发生?也许随着对实际发生的事情的深入了解,我可以做出更好的错误报告。
    • 看看我在问题中编辑的 JSFiddles。
    猜你喜欢
    • 2015-11-17
    • 2017-06-08
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    相关资源
    最近更新 更多