Die Beziehung zwischen Failure
und Exception
besteht darin, dass a ein Failure
hat Exception
- das heißt, es enthält das Ausnahmeobjekt als Teil seines Zustands. Etwas wie das:
class Failure {
has Exception $.exception;
# ...
}
Wenn ein Failure
"explodiert", tut es dies, indem es das wirft Exception
, was sich darin befindet. Was also den CATCH
Block erreicht , ist das Exception
Objekt, und es gibt keine Verbindung zurück zum Gehäuse Failure
. (Tatsächlich könnte ein gegebenes Exception
Objekt im Prinzip von vielen Failure
s gehalten werden.)
Daher gibt es keinen direkten Weg, dies zu erkennen. Aus gestalterischer Sicht sollten Sie es wahrscheinlich nicht sein und einen anderen Weg finden, um Ihr Problem zu lösen. A Failure
ist nur eine Möglichkeit, das Auslösen einer Ausnahme zu verschieben und zuzulassen, dass sie als Wert behandelt wird. Es ist nicht beabsichtigt, dass sich die Art des zugrunde liegenden Problems ändert, da es eher als Wert als als sofortige Übertragung des Kontrollflusses vermittelt wird. Leider wurde das ursprüngliche Ziel in der Frage nicht angegeben; Möglicherweise ist es hilfreich, sich Steuerungsausnahmen anzusehen, andernfalls stellen Sie möglicherweise eine andere Frage zu dem zugrunde liegenden Problem, das Sie lösen möchten. Es gibt wahrscheinlich einen besseren Weg.
Der Vollständigkeit halber werde ich beachten Sie, dass es indirekte Weise , dass man erkennen kann , dass die Exception
durch ein geworfen wurde Failure
. Wenn Sie beispielsweise .backtrace
das Ausnahmeobjekt abrufen und sich das Paket des oberen Frames ansehen, können Sie feststellen, dass es aus dem Failure
folgenden Verzeichnis stammt :
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
Dies hängt jedoch stark von Implementierungsdetails ab, die sich leicht ändern können, sodass ich mich nicht darauf verlassen würde.