La relation entre Failure
et Exception
est que a Failure
a un Exception
- c'est-à-dire qu'il détient l'objet d'exception comme faisant partie de son état. Quelque chose comme ça:
class Failure {
has Exception $.exception;
# ...
}
Lorsqu'un Failure
"explose", il le fait en lançant ce Exception
qui est à l'intérieur. Ainsi, ce qui atteint le CATCH
bloc est l' Exception
objet, et il n'y a pas de lien vers l'enveloppe Failure
. (En fait, un Exception
objet donné pourrait en principe être détenu par de nombreux Failure
art.)
Par conséquent, il n'y a aucun moyen direct de détecter cela. Du point de vue de la conception, vous ne devriez probablement pas l'être et devriez trouver une manière différente de résoudre votre problème. A Failure
est juste un moyen de différer le lancement d'une exception et de la traiter comme une valeur; il n'est pas prévu que la nature du problème sous-jacent change car il est transmis comme une valeur plutôt que comme un transfert immédiat du flux de contrôle. Malheureusement, l'objectif initial n'était pas indiqué dans la question; vous trouverez peut-être utile d'examiner les exceptions de contrôle, mais sinon, posez peut-être une autre question sur le problème sous-jacent que vous essayez de résoudre. Il y a probablement une meilleure façon.
Par souci d'exhaustivité, je noterai qu'il existe des moyens indirects que l'on peut détecter que le a Exception
été lancé par un Failure
. Par exemple, si vous obtenez l' .backtrace
objet d'exception et regardez le package du cadre supérieur, il est possible de déterminer qu'il provient de Failure
:
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
Cependant, cela dépend fortement des détails d'implémentation qui pourraient facilement changer, donc je ne m'y fierais pas.