Отношение между Failure
и Exception
заключается в том, что Failure
имеет Exception
, то есть он содержит объект исключения как часть своего состояния. Примерно так:
class Failure {
has Exception $.exception;
# ...
}
Когда Failure
«взрывается», он делает это, бросая Exception
, который находится внутри него. Таким образом, то, что достигает блока CATCH
, является объектом Exception
, и нет обратной связи с вмещающим Failure
. (На самом деле, данный Exception
объект в принципе может удерживаться многими Failure
с.)
Следовательно, прямого способа обнаружить это нет. С точки зрения дизайна, вы, вероятно, не должны, и должны найти другой способ решения вашей проблемы. 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
}
}
Однако это сильно зависит на детали реализации, которые могут легко измениться, поэтому я бы не стал на это полагаться.