La relación entre Failure
y Exception
es que unFailure
tiene un Exception
- es decir, contiene el objeto de excepción como parte de su estado. Algo como esto:
class Failure {
has Exception $.exception;
# ...
}
Cuando un Failure
"explota", lo hace arrojando el Exception
que está dentro de él. Por lo tanto, lo que llega al CATCH
bloque es el Exception
objeto, y no hay un enlace de regreso al recinto.Failure
. (De hecho, un Exception
objeto dado podría ser mantenido en principio por muchos Failure
s.)
Por lo tanto, no hay una forma directa de detectar esto. Desde una perspectiva de diseño, probablemente no debería serlo, y debería encontrar una forma diferente de resolver su problema. A Failure
es solo una forma de diferir el lanzamiento de una excepción y permitir que se trate como un valor; No se pretende que la naturaleza del problema subyacente cambie porque se transmite como un valor y no como una transferencia inmediata del flujo de control. Desafortunadamente, el objetivo original no se indicó en la pregunta; puede que le resulte útil observar las excepciones de control, pero de lo contrario, quizás publique otra pregunta sobre el problema subyacente que está tratando de resolver. Probablemente hay una mejor manera.
Para completar, voy a señalar que hay son formas indirectas que uno puede detectar que el Exception
fue arrojado por una Failure
. Por ejemplo, si obtiene el .backtrace
objeto de excepción y mira el paquete del marco superior, es posible determinar que proviene de Failure
:
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
Sin embargo, esto depende en gran medida de los detalles de implementación que podrían cambiar fácilmente, por lo que no confiaría en ello.