La relation entre Failureet Exceptionest que a Failurea 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 Exceptionqui est à l'intérieur. Ainsi, ce qui atteint le CATCHbloc est l' Exceptionobjet, et il n'y a pas de lien vers l'enveloppe Failure. (En fait, un Exceptionobjet donné pourrait en principe être détenu par de nombreux Failureart.)
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 Failureest 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' .backtraceobjet 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.