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.
try
bloco implica ouse fatal
pragma, o que significa que qualquerFailure
retorno de uma chamada feita no bloco é imediatamente convertido em uma exceção. Apenas não usetry
; umCATCH
pode ir em qualquer quarteirão de Raku (então, basta colocá-lo no nível dosub
). Como alternativa, escrevano fatal
na parte superior do seutry
bloco.True
na versão Rakudo que tenho localmente. Se isso não acontecer com o seu, isso prova o ponto de vista da fragilidade de fazer isso.Basta remover o
try
invólucro:Você usou
try
. Atry
faz algumas coisas, mas a coisa pertinente aqui é que ele diz ao Raku para promover imediatamente qualquerFailure
s no seu escopo, com exceções - que é o que você diz que não quer. Portanto, a solução mais simples é parar de fazer isso.Esta resposta apenas repete verbalmente parte da explicação de jnthn (veja em particular comentários que ele escreveu abaixo de sua resposta). Mas eu não estava convencido de que todos os leitores perceberiam esse aspecto e não achei que um comentário ou dois sobre a resposta de jnthn ajudariam, daí essa resposta.
Escrevi isso como uma resposta da comunidade para garantir que não vou me beneficiar de nenhum voto positivo, porque obviamente não garante isso. Se o número de votos for suficiente, vamos excluí-lo.
fonte