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.
try
Blok implikuje pragmęuse fatal
, co oznacza, że każde zwrotneFailure
wywołanie wykonane w bloku jest natychmiast przekształcane w wyjątek. Po prostu nie używajtry
; aCATCH
może przejść w dowolnym bloku w Raku (więc po prostu trzymaj go na poziomiesub
). Możesz też napisaćno fatal
u górytry
bloku.True
na wersji Rakudo, którą mam lokalnie. Jeśli to nie zależy od ciebie, to tylko dowodzi, że kruchość jest taka.Wystarczy usunąć
try
opakowanie:Użyłeś
try
.try
Robi kilka rzeczy, ale istotne jest tutaj to, że mówi Raku natychmiast promować żadnychFailure
S w jego zakres wyjątków - czyli to, co mówisz, że nie chcesz. Więc najprostszym rozwiązaniem jest po prostu przestać to robić.Ta odpowiedź po prostu werbalnie powtarza część wyjaśnień Jnthna (patrz w szczególności komentarze, które napisał poniżej swojej odpowiedzi). Ale nie byłem przekonany, że wszyscy czytelnicy zauważą / zrozumieją ten aspekt, i nie sądziłem, że komentarz lub dwa na temat odpowiedzi Jnthna pomogłyby, stąd ta odpowiedź.
Napisałem to jako odpowiedź społeczności, aby upewnić się, że nie skorzystam z żadnych głosów poparcia, ponieważ oczywiście nie jest to uzasadnione. Jeśli otrzyma wystarczającą liczbę głosów negatywnych, po prostu go usuniemy.
źródło