简体   繁体   English

AMPHP 抛出一个无法捕获的 MultiReasonException - 这是一个错误吗?

[英]AMPHP throws an uncatchable MultiReasonException - Is this a bug?

I'm getting a MultiReasonException thrown during a DNS lookup as part of a AMP Socket connect call.作为 AMP Socket 连接调用的一部分,我在 DNS 查找过程中抛出了MultiReasonException The actual exception thrown is an NX domain, which is fine - the lookup is for a host which is down currently.抛出的实际异常是一个 NX 域,这很好 - 查找是针对当前关闭的主机。 The problem is I cannot catch and handle the exception - it ends up at the loop level where I am able to catch it, but it's no use at that point.问题是我不能捕捉和处理异常-它在循环水平,能赶上它结束了,但它是在这一点上没有用。

I tried to reproduce in a simple test script for posting here, but it works correctly if I just do:我试图在一个简单的测试脚本中复制以在此处发布,但如果我这样做,它可以正常工作:

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

and wrap it in a try catch I'm able to catch the DNS exception - it doesn't even throw a MultiReasonException .并将其包装在 try catch 中,我能够捕获 DNS 异常 - 它甚至不会抛出MultiReasonException I think this is something to do with the fact my actual application has a lot more going on "concurrently" which means the loop actually goes off and does other stuff while waiting for the DNS request to fail ("defers" the dns lookup coroutine).认为这与我的实际应用程序有更多“并发”进行的事实有关,这意味着循环实际上会关闭并在等待 DNS 请求失败时执行其他操作(“延迟”dns 查找协程) . This appears to cause the exception to be thrown wrapped in a MultiReasonException for some reason (there is only 1 exception listed in the Mutli in xdebug).由于某种原因,这似乎导致异常被抛出包装在MultiReasonException中(在 xdebug 的 Mutli 中只列出了 1 个异常)。 What's more, the MultiReasonException is not thrown into my coroutine where the connect call was made, it just ends up being thrown into the Loop::run call - and this is the real problem.更重要的是, MultiReasonException没有被抛出到我进行连接调用的协同程序中,它最终被抛出到Loop::run调用中——这才是真正的问题。 I cannot handle the exception here, since it's not in the calling context and could be from anywhere in the code.我无法处理这里的异常,因为它不在调用上下文中,并且可能来自代码中的任何地方。

Can anyone help shed any light on this, or even point me in the right direction to pin this down a little more?任何人都可以帮助阐明这一点,或者甚至指出我正确的方向以进一步确定这一点? I'm all out of ideas.我都没有想法了。 Trying to trace this thing through a massive stack full of Coroutines and Placeholder functions is a nightmare.试图通过充满协程和占位符函数的大量堆栈来追踪这件事是一场噩梦。 How on Earth do you debug such things through the AMP stack?你到底是如何通过 AMP 堆栈调试这些东西的?

In case anyone else has a similar problem I think I found the answer to my own question.如果其他人有类似的问题,我想我找到了自己问题的答案。

It's a subtlety of how the Amp stack handles exceptions.这是 Amp 堆栈如何处理异常的微妙之处。 I was calling the amp function some on 1 or more promises in a high level function.我打电话放大器功能some在高级别功能1分或更多的承诺。 This acted on a promise chain which eventually led down to a function that made a DNS lookup.这作用于一个承诺链,最终导致一个进行 DNS 查找的函数。 When the DNS lookup failed and threw a DNS related exception (which I wasn't catching in the Promise) it percolated up the promise chain to the some, which it appears always throws a MultiReasonException even if it has only 1 promise it's acting on.当 DNS 查找失败并抛出与 DNS 相关的异常(我没有在 Promise 中捕获)时,它会将承诺链向上渗透到一些,它似乎总是抛出MultiReasonException即使它只有 1 个它正在执行的承诺。 This meant that the I always got a MultiReasonException which contained the DNS exception.这意味着我总是得到一个包含 DNS 异常的MultiReasonException This would be fine, except when I looked a the stack trace for the DNS related exception, it of course did not contain any of my functions - so I could not see how it could be caught (I also did not just try to catch it at the source, which it turns out would have worked, but looked from the trace like it wouldn't).这会很好,除非我查看与 DNS 相关的异常的堆栈跟踪,它当然不包含我的任何函数 - 所以我看不到它是如何被捕获的(我也没有试图捕获它在源头,事实证明它会起作用,但从跟踪中看起来好像它不会)。

This is because the exception is thrown during a time when amp was on a subsequent tick, and thus my code was not currently on the stack.这是因为在 amp 处于后续滴答时抛出异常,因此我的代码当前不在堆栈中。 Once the exception was thrown by code in the AMP stack, the trace in the exception is of course locked in. It would then be thrown back into my original promise (generator) which requested the lookup, where it could have been caught, but since I wasn't catching it, it got thrown all the way up to the some call, where it confused me by appearing as a MultiReasonException .一旦异常被 AMP 堆栈中的代码抛出,异常中的跟踪当然会被锁定。然后它会被扔回我的原始承诺(生成器),它请求查找,在那里它可以被捕获,但是由于我没有抓住它,它一直被抛出到some调用,在那里它显示为MultiReasonException我感到困惑。

I'm not sure how coherent that is, but maybe it will help somebody.我不确定这有多连贯,但也许它会帮助某人。 Moral of the story - don't try to be clever - just catch the relevant exception where you yield the promise that will throw it.这个故事的寓意 - 不要试图变得聪明 - 只要抓住相关的异常,你就会产生会抛出它的承诺。 The exception stack traces can be misleading in AMP. AMP 中的异常堆栈跟踪可能会产生误导。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM