A relação entre Failuree Exceptioné que a Failurepossui 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 Exceptionque está dentro dele. Assim, o que atinge o CATCHbloco é o Exceptionobjeto, e não há link para o anexo Failure. (De fato, um determinado Exceptionobjeto poderia, em princípio, ser mantido por muitos Failures.)
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 Exceptionfoi jogado por um Failure. Por exemplo, se você obtém o .backtraceobjeto 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.