Zależność między Failurei Exceptionpolega na tym, że a Failurema Exception- to znaczy, że przechowuje obiekt wyjątku jako część swojego stanu. Coś takiego:
class Failure {
has Exception $.exception;
# ...
}
Kiedy Failure„eksploduje”, robi to, wrzucając to, Exceptionco jest w środku. Tak więc to, co dociera do CATCHbloku, to Exceptionobiekt i nie ma żadnego łącza z powrotem do otaczającego Failure. (W rzeczywistości dany Exceptionprzedmiot może w zasadzie być w posiadaniu wielu osób Failure.)
Dlatego nie ma bezpośredniego sposobu na wykrycie tego. Z punktu widzenia projektowania prawdopodobnie nie powinieneś być i powinieneś znaleźć inny sposób rozwiązania swojego problemu. A Failurejest po prostu sposobem na odłożenie wyjątku i umożliwienie traktowania go jako wartości; nie ma na celu zmiany charakteru problemu leżącego u podstaw problemu, ponieważ jest on przekazywany jako wartość, a nie jako natychmiastowe przeniesienie przepływu sterowania. Niestety pierwotny cel nie został podany w pytaniu; przydatne może okazać się przyjrzenie się wyjątkom kontrolnym, ale w innym przypadku może zadać kolejne pytanie na temat problemu, który próbujesz rozwiązać. Prawdopodobnie jest lepszy sposób.
Dla kompletności, będę pamiętać, że nie są pośrednie sposoby, które można wykryć, że Exceptionzostał wyrzucony przez Failure. Na przykład, jeśli uzyskasz .backtraceobiekt wyjątku i spojrzysz na pakiet górnej ramki, możesz ustalić, że pochodzi on z Failure:
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
Jest to jednak w dużej mierze zależne od szczegółów implementacji, które można łatwo zmienić, więc nie polegam na tym.