我们知道,可以通过CATCH块来处理故障。
在下面的示例中,我们在“ other-sub”中创建一个“ AdHoc”失败,并在CATCH块中(在“ my-sub”中)处理异常。
sub my-sub {
try {
CATCH {
when X::AdHoc { say 'AdHoc Exception handled here'; .resume }
default {say 'Other Exception'; .resume}
}
my $b = other-sub();
$b.so ?? $b.say !! 'This was a Failure'.say;
}
}
sub other-sub { fail 'Failure_X' }
my-sub();
输出如下:
AdHoc Exception handled here
This was a Failure
我的问题是:为了区分两种情况,如何区分CATCH块中的“失败”和“正常”异常?
之间的关系Failure
,并Exception
是一个Failure
有一个Exception
-也就是说,它拥有异常对象作为其状态的一部分。像这样:
class Failure {
has Exception $.exception;
# ...
}
当Failure
“爆炸”时,它通过将其Exception
内部的抛出来实现。因此,到达CATCH
块的是Exception
对象,没有链接返回到封闭的Failure
。(实际上,一个给定的Exception
对象原则上可以由许多人持有Failure
。)
因此,没有直接的方法可以检测到这一点。从设计的角度来看,您可能不应该这样做,应该找到解决问题的另一种方法。AFailure
只是一种推迟抛出异常并将其视为值的方式;这并不意味着根本问题的性质会发生变化,因为它是作为一个值而不是作为控制流的立即传递来传达的。不幸的是,最初的目标并未在问题中阐明。您可能会发现查看控件异常很有用,但否则可能会发布另一个有关您要解决的基本问题的问题。可能有更好的方法。
为了完整起见,我将注意,有一些间接方法可以检测到Exception
抛出了Failure
。例如,如果获取.backtrace
异常对象的并查看顶部框架的包,则可以确定它来自Failure
:
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
但是,这在很大程度上取决于可以轻松更改的实现细节,因此我不会依赖它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句