Отношение между 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
}
}
Однако это сильно зависит от деталей реализации, которые могут легко измениться, поэтому я бы не стал на это полагаться.