A relação entre Failure
e Exception
é que a Failure
possui um Exception
- ou seja, mantém o objeto de exceção como parte de seu estado. Algo assim:
class Failure {
has Exception $.exception;
# ...
}
Quando um Failure
"explode", ele faz isso jogando o Exception
que está dentro dele. Assim, o que atinge o CATCH
bloco é o Exception
objeto, e não há link para o anexo Failure
. (De fato, um determinado Exception
objeto poderia, em princípio, ser mantido por muitos Failure
s.)
Portanto, não há maneira direta de detectar isso. Do ponto de vista do design, você provavelmente não deveria estar e deve encontrar uma maneira diferente de resolver seu problema. A Failure
é apenas uma maneira de adiar o lançamento de uma exceção e permitir que ela seja tratada como um valor; não se pretende que a natureza do problema subjacente mude porque é transmitida como um valor e não como uma transferência imediata do fluxo de controle. Infelizmente, o objetivo original não foi declarado na pergunta; você pode achar útil examinar exceções de controle, mas, caso contrário, talvez poste outra pergunta sobre o problema subjacente que você está tentando resolver. Provavelmente existe uma maneira melhor.
Para completar, eu vou note que não são formas indiretas que se pode detectar que o Exception
foi jogado por um Failure
. Por exemplo, se você obtém o .backtrace
objeto de exceção e observa o pacote do quadro superior, é possível determinar que ele vem do Failure
:
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
No entanto, isso depende muito dos detalhes da implementação que podem mudar facilmente, então eu não confiaria nisso.