Failures and Soft Errors
When to use what: fail for expected, recoverable errors in library functions (callers choose to check or let it throw); die for exceptional conditions and bugs.
use fatal; makes Failures throw immediately within a lexical scope.
# fail returns an unthrown exception (a Failure): it explodes only if used carelessly
sub parse-int(Str $s) {
return $s.Int if $s ~~ /^ '-'? \d+ $/;
fail "Not an integer: '$s'";
}
my $good = parse-int('42');
my $bad = parse-int('abc');
say $good + 1; # 43
say $bad.defined; # False (checking definedness or truthiness "handles" the Failure)
with parse-int('xyz') { say "Parsed $_" } else { say "Failed: {.exception.message}" }
say parse-int('7') // 0; # 7
say parse-int('?') // 0; # 0 (// handles the Failure)
# say $bad + 1; # this would throw: the Failure is "used"
# Built-ins that return Failures
my $n = 'abc'.Int; # Failure (X::Str::Numeric)
say $n.so; # False
my $fh = open 'missing-file.txt'; # Failure (doesn't throw until used)
say "can't open" unless $fh;
# Unhandled Failures throw when they're sunk (discarded) or used
# 'abc'.Int; # would throw when sunk
# orelse / andthen chains
my $value = parse-int('oops') orelse 'default';
say $value; # default
parse-int('10') and
…