在Raku的CATCH块中区分Failure与常规Exception的方法
如何在Raku的CATCH块中区分Failure与常规Exception
好问题!在Raku里,fail生成的Failure和直接抛出的常规Exception确实容易混淆——因为Failure被强制求值时会自动抛出对应的Exception(比如你例子里的X::AdHoc)。不过我们可以通过以下方法在CATCH块里精准区分两者:
核心思路:检查Exception的payload属性
当Failure被触发抛出Exception时,这个Exception的payload属性会保存原始的Failure对象;而直接用.throw抛出的常规Exception,它的payload一般是错误文本或自定义数据,不会是Failure类型。我们可以利用这一点做区分。
修改你的代码示例演示
我调整了你的代码,加入了常规Exception的测试,同时在CATCH块里做区分判断:
sub my-sub { try { CATCH { when X::AdHoc { # 检查当前Exception的payload是否为Failure if .payload ~~ Failure { say 'AdHoc Exception from Failure handled here'; .resume; } else { say 'Regular AdHoc Exception handled here'; .resume; } } default { if .payload ~~ Failure { say 'Other Exception triggered by Failure'; } else { say 'Other regular Exception'; } .resume } } # 调用返回Failure的函数 my $b = other-sub(); $b.so ?? $b.say !! 'This was a Failure'.say; # 主动抛出一个常规AdHoc Exception X::AdHoc.new(payload => 'Manual regular error').throw; } } sub other-sub { fail 'Failure_X' } my-sub();
运行输出:
AdHoc Exception from Failure handled here This was a Failure Regular AdHoc Exception handled here
补充:提前捕获Failure(非CATCH块场景)
如果你不需要等到CATCH块统一处理,也可以在获取函数返回值时直接判断是否为Failure类型,这样能更早处理:
my $b = other-sub(); if $b ~~ Failure { say "Got a Failure: $b.error"; # 自定义处理逻辑 } else { # 正常使用返回值 }
这个方法更直接,但如果你的代码结构里必须在CATCH块统一处理异常,那么第一种检查payload的方式更适配你的需求。
内容的提问来源于stack exchange,提问作者jakar
相关产品推荐
相关产品推荐

