Взаємозв'язок між Failureі Exceptionполягає в тому, що у a 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
}
}
Однак це сильно залежить від деталей впровадження, які можна легко змінити, тому я не покладався на це.