【问题标题】:AMPHP throws an uncatchable MultiReasonException - Is this a bug?AMPHP 抛出无法捕获的 MultiReasonException - 这是一个错误吗?
【发布时间】:2020-11-10 23:59:21
【问题描述】:

作为 AMP 套接字连接调用的一部分,我在 DNS 查找期间收到了 MultiReasonException。抛出的实际异常是一个 NX 域,这很好 - 查找是针对当前关闭的主机。问题是我无法捕获和处理异常 - 它最终在我能够捕获它的循环级别结束,但此时它没有用。

我试图在一个简单的测试脚本中重现以在此处发布,但如果我这样做,它可以正常工作:

Loop::run(function(){
 $res = yield \Amp\Dns\resolve("tp-link-hs110-5");
 var_dump($res);
}); 

并将其包装在 try catch 中,我能够捕获 DNS 异常 - 它甚至不会抛出 MultiReasonException。我认为这与我的实际应用程序“并发”执行更多操作这一事实有关,这意味着循环实际上会在等待 DNS 请求失败时停止并执行其他操作(“推迟” dns 查找协程)。出于某种原因,这似乎导致异常被包裹在MultiReasonException 中(xdebug 中的 Mutli 中仅列出了 1 个异常)。更重要的是,MultiReasonException 并没有被扔到我进行连接调用的协程中,它最终被扔到了 Loop::run 调用中——这是真正的问题。我无法在此处处理异常,因为它不在调用上下文中,并且可能来自代码中的任何位置。

任何人都可以帮助阐明这一点,或者甚至为我指出正确的方向以进一步确定这一点吗?我完全没主意了。试图通过一个充满协程和占位符函数的 大量 堆栈来追踪这个东西是一场噩梦。您到底是如何通过 AMP 堆栈调试这些东西的?

【问题讨论】:

    标签: php amphp


    【解决方案1】:

    如果其他人有类似的问题,我想我找到了自己问题的答案。

    这是 Amp 堆栈如何处理异常的微妙之处。我在高级函数中的 1 个或多个 Promise 上调用了 amp 函数 some。这作用于一个承诺链,最终导致一个进行 DNS 查找的函数。当 DNS 查找失败并抛出与 DNS 相关的异常(我没有在 Promise 中捕获)时,它会将 Promise 链渗透到某些地方,它似乎总是抛出 MultiReasonException,即使它只有 1 个 Promise 它正在执行在。这意味着我总是得到一个包含 DNS 异常的MultiReasonException。这很好,除了当我查看与 DNS 相关的异常的堆栈跟踪时,它当然不包含我的任何函数 - 所以我看不到它是如何被捕获的(我也没有试图捕获它在源头上,事实证明这是可行的,但从跟踪中看起来好像不行)。

    这是因为异常是在 amp 处于后续滴答时引发的,因此我的代码当前不在堆栈中。一旦异常被 AMP 堆栈中的代码抛出,异常中的跟踪当然会被锁定。然后它会被扔回我原来请求查找的承诺(生成器)中,它可能已经被捕获了,但是因为我没有抓住它,它一直被抛出到some 调用,它以MultiReasonException 的形式出现让我感到困惑。

    我不确定这是否连贯,但也许它会对某人有所帮助。故事的寓意——不要试图变得聪明——只要抓住相关的异常,你就会产生将抛出它的承诺。异常堆栈跟踪可能会在 AMP 中产生误导。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-22
      • 1970-01-01
      • 2023-03-28
      • 2016-11-14
      • 1970-01-01
      • 2020-08-24
      相关资源
      最近更新 更多