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.
try
bloc implique leuse fatal
pragma, ce qui signifie que toutFailure
retour d'un appel effectué dans le bloc est immédiatement converti en exception. N'utilisez simplement pastry
; unCATCH
peut aller dans n'importe quel bloc de Raku (il suffit donc de l'avoir au niveau dusub
). Vous pouvez également écrireno fatal
en haut de votretry
bloc.True
sur la version Rakudo que j'ai en local. Si ce n'est pas le cas pour vous, cela prouve simplement la fragilité de faire cela.Retirez simplement l'
try
emballage:Vous avez utilisé
try
. Atry
fait quelques choses, mais ce qui est pertinent ici, c'est qu'il dit à Raku de promouvoir immédiatement toutFailure
s dans sa portée en exceptions - c'est ce que vous dites que vous ne voulez pas . La solution la plus simple consiste donc à ne plus faire cela.Cette réponse ne fait que répéter verbalement une partie de l'explication de jnthn (voir en particulier les commentaires qu'il a écrits ci-dessous sa réponse). Mais je n'étais pas convaincu que tous les lecteurs remarqueraient / comprendraient cet aspect, et je ne pensais pas qu'un ou deux commentaires sur la réponse de jnthn aideraient, d'où cette réponse.
J'ai écrit cela comme une réponse de la communauté pour m'assurer que je ne bénéficierai d'aucun vote positif, car cela ne le justifie évidemment pas. S'il obtient suffisamment de votes négatifs, nous le supprimerons simplement.
la source