Отношение между Failure
и Exception
заключается в том, что a Failure
имеет Exception
- то есть оно содержит объект исключения как часть своего состояния. Что-то вроде этого:
class Failure {
has Exception $.exception;
# ...
}
Когда Failure
«взрывается», он делает это, бросая то, Exception
что находится внутри него. Таким образом, то, что достигает CATCH
блока, является Exception
объектом, и нет обратной ссылки на вложение Failure
. (На самом деле, данный Exception
объект в принципе может удерживаться многими Failure
с.)
Следовательно, нет прямого способа обнаружить это. С точки зрения дизайна, вы, вероятно, не должны, и должны найти другой способ решения вашей проблемы. A Failure
- это просто способ отложить выдачу исключения и позволить ему рассматриваться как значение; не предполагается, что природа основной проблемы меняется, потому что она передается как значение, а не как непосредственная передача потока управления. К сожалению, первоначальная цель не была указана в вопросе; вам может быть полезно взглянуть на исключения управления, но в противном случае, возможно, опубликуйте другой вопрос об основной проблеме, которую вы пытаетесь решить. Там, наверное, лучший способ.
Для полноты картины отмечу , что есть косвенные способы , которые можно обнаружить , что Exception
был брошенной Failure
. Например, если вы получили .backtrace
объект исключения и посмотрите на пакет верхнего фрейма, можно определить, что он исходит из Failure
:
sub foo() { fail X::AdHoc.new(message => "foo") }
try {
foo();
CATCH {
note do { no fatal; .backtrace[0].code.package ~~ Failure };
.resume
}
}
Однако это сильно зависит от деталей реализации, которые могут легко измениться, поэтому я бы не стал на это полагаться.