Курс языка программирования Raku / Объекты, ввод-вывод и исключения / Исключения
Мягкие сбои
Бросить исключение через die — значит немедленно всё
остановить. Иногда это слишком резко: вы хотите, чтобы подпрограмма
сообщила о невозможности выдать результат, но решение, фатально ли это,
оставила вызывающей стороне. Для этого в Raku есть мягкие сбои,
создаваемые с помощью fail.
Когда подпрограмма вызывает fail, она не бросает
исключение сразу. Вместо этого она возвращает вызывающей стороне особый
объект Failure. Failure не определён, поэтому
вызывающий код может тихо его проверить:
sub divide($a, $b) {
fail 'cannot divide by zero' if $b == 0;
return $a / $b;
}
say divide(10, 2); # 5
say divide(10, 0).defined; # FalseУспешный вызов возвращает 5. Неудачный возвращает
Failure, который на defined отвечает
False, так что вызывающая сторона может проверить
результат, прежде чем им пользоваться.
Failure называется мягким потому, что
превращается в настоящее брошенное исключение, только если попытаться
использовать его как значение, не проверив предварительно. Пока вы его
обрабатываете — например, проверяете defined, — он остаётся
безмолвным. Это позволяет подпрограмме сообщить о проблеме, не заставляя
всю программу остановиться.
Вы это уже видели
Такой отложенный стиль сбоя присущ не только fail.
Раньше в этой части вы дважды встречали ту же идею.
Деление на ноль тихо порождает значение и бросает исключение лишь тогда, когда вы им действительно воспользуетесь:
my $x = 1 / 0; # ошибки пока нет
say $x; # бросает только здесь, когда значение используетсяНеудачно завершившаяся внешняя программа возвращает
Proc, который бросает исключение, только если вы отбросите
его необработанным; сохраните и исследуйте его — и он останется
безмолвным значением:
run 'sh', '-c', 'exit 1'; # неудачный Proc отброшен, поэтому здесь бросается исключениеВ каждом случае проблема не останавливает программу в тот миг, когда возникает: она становится значением, которое можно проверить, и перерастает в брошенное исключение, только если воспользоваться им без проверки или проигнорировать его. Тема Не всякая ошибка возникает сразу показывает эти два случая рядом.
Практика
Пройдите 1 тест по содержанию этой темы.
Упражнения
В этом разделе 3 упражнения. Прежде чем приступать к практике, изучите все темы раздела.