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