La relazione tra Failure
e Exception
è che a Failure
ha unException
- vale a dire, contiene l'oggetto eccezione come parte del suo stato. Qualcosa come questo:
class Failure {
has Exception $.exception;
# ...
}
Quando un Failure
"esplode", lo fa lanciando Exception
ciò che è al suo interno. Pertanto, ciò che raggiunge il CATCH
blocco è l' Exception
oggetto, e non vi è alcun collegamento con il recinto Failure
. (In effetti, un datoException
oggetto potrebbe in linea di principio essere trattenuto da molti Failure
s.)
Pertanto, non esiste un modo diretto per rilevare questo. Dal punto di vista del design, probabilmente non dovresti esserlo e dovresti trovare un modo diverso di risolvere il tuo problema. UNFailure
è solo un modo per rinviare il lancio di un'eccezione e consentire che venga trattato come un valore; non si intende che la natura del problema sottostante cambi perché viene trasmessa come valore anziché come trasferimento immediato del flusso di controllo. Sfortunatamente, l'obiettivo iniziale non era indicato nella domanda; potresti trovare utile esaminare le eccezioni di controllo, ma in caso contrario potresti pubblicare un'altra domanda sul problema di fondo che stai cercando di risolvere. Probabilmente c'è un modo migliore.
Per completezza, noterò che ci sono modi indiretti in cui si può rilevare che il è Exception
stato lanciato da a Failure
. Ad esempio, se si ottiene l' .backtrace
oggetto dell'eccezione e si osserva il pacchetto del frame superiore, è possibile determinare che proviene da Failure
:
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
Tuttavia, questo dipende fortemente dai dettagli di implementazione che potrebbero facilmente cambiare, quindi non mi affiderei.