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.
try
bloque implica eluse fatal
pragma, lo que significa que cualquierFailure
devolución de una llamada realizada en el bloque se convierte inmediatamente en una excepción. Simplemente no lo usestry
; aCATCH
puede ir en cualquier bloque en Raku (así que solo tenlo al nivel desub
). Alternativamente, escribano fatal
en la parte superior de sutry
bloque.True
en la versión Rakudo que tengo localmente. Si no lo hace en el suyo, eso solo prueba el punto sobre la fragilidad de hacer esto.Simplemente retire el
try
envoltorio:Que utilizó
try
. Atry
hace algunas cosas, pero lo pertinente aquí es que le dice a Raku que promueva inmediatamente cualquierFailure
s en su alcance a excepciones, que es lo que usted dice que no quiere. Entonces, la solución más simple es dejar de hacerlo.Esta respuesta simplemente repite parte de la explicación de jnthn (ver en particular los comentarios que escribió debajo de su respuesta). Pero no estaba convencido de que todos los lectores detectaran / entendieran este aspecto, y no pensé que un comentario o dos sobre la respuesta de jnthn ayudarían, de ahí esta respuesta.
He escrito esto como una respuesta de la comunidad para asegurarme de que no me beneficiaré de ningún voto positivo porque obviamente no lo garantiza. Si recibe suficientes votos negativos, lo eliminaremos.
fuente