Zależność między Failure
i Exception
polega na tym, że a Failure
ma 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, Exception
co jest w środku. Tak więc to, co dociera do CATCH
bloku, to Exception
obiekt i nie ma żadnego łącza z powrotem do otaczającego Failure
. (W rzeczywistości dany Exception
przedmiot 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 Failure
jest 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 Exception
został wyrzucony przez Failure
. Na przykład, jeśli uzyskasz .backtrace
obiekt 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.