Failure Reference
Delayed exception
What it is #
Routines #
Signatures are reproduced from the documentation, including their declared return types. A routine listed here is part of the type's published interface; whether Raku++ implements it is a separate question, answered by the examples below.
method new #
multi method new(Failure:D:)
multi method new(Failure:U:)
multi method new(Failure:U: Exception:D \exception)
multi method new(Failure:U: $payload)
multi method new(Failure:U: |cap (*@msg))
Returns a new Failure instance with payload given as argument. If called without arguments on a Failure object, it will throw; on a type value, it will create an empty Failure with no payload. The latter can be either an Exception or a payload for an Exception. A typical payload would be a Str with an error message. A list of payloads is also accepted.
method handled #
method handled(Failure:D: --> Bool:D) is rw
Returns Bool:D.
Returns True for handled failures, False otherwise. The handled method is an lvalue, see routine trait is rw, which means you can also use it to set the handled state:
method exception #
method exception(Failure:D: --> Exception)
Returns Exception.
Returns the Exception object that the failure wraps.
method self #
method self(Failure:D: --> Failure:D)
Returns Failure:D.
If the invocant is a handled Failure, returns it as is. If not handled, throws its Exception. Since Mu type provides .self for every class, calling this method is a handy way to explosively filter out Failures:
method Bool #
multi method Bool(Failure:D: --> Bool:D)
Returns Bool:D.
Returns False, and marks the failure as handled.
method Capture #
method Capture()
Throws X::Cannot::Capture if the invocant is a type object or a handled Failure. Otherwise, throws the invocant's exception.
method defined #
multi method defined(Failure:D: --> Bool:D)
Returns Bool:D.
Returns False (failures are officially undefined), and marks the failure as handled.
method list #
multi method list(Failure:D:)
Marks the failure as handled and throws the invocant's exception.
sub fail #
multi fail(--> Nil)
multi fail(*@text)
multi fail(Exception:U $e --> Nil )
multi fail($payload --> Nil)
multi fail(|cap (*@msg) --> Nil)
multi fail(Failure:U $f --> Nil)
multi fail(Failure:D $fail --> Nil)
Returns Nil.
Exits the calling Routine and returns a Failure object wrapping the exception $e - or, for the cap or $payload form, an X::AdHoc exception constructed from the concatenation of @text. If the caller activated fatal exceptions via the pragma use fatal;, the exception is thrown instead of being returned as a Failure. If it's called with a generic Failure, an ad-hoc undefined failure is
Examples, run three ways #
Every example below comes from the official documentation, together with the output that documentation asserts. Each was then executed by Rakudo and by Raku++ when this page was built. Where the three agree, one result is shown; where they do not, all three are — because which of them is wrong is exactly the information worth having.
2 all-differ · 8 no-output · 2 not-runnable · 6 ok
class Failure is Nil { }Not executed: the documentation states no expected output for this example.
sub may_fail( --> Numeric:D ) {
my $value = (^10).pick || fail "Zero is unacceptable";
fail "Odd is also not okay" if $value % 2;
return $value;
}
with may_fail() -> $value { # defined, so didn't fail
say "I know $value isn't zero or odd."
} else { # undefined, so failed, and the Failure is the topic
say "Uh-oh: {.exception.message}."
}Not executed: the documentation states no expected output for this example.
my $e = Failure.new(now.DateTime, 'WELP‼');
say $e;
CATCH{ default { say .^name, ': ', .Str } }
# OUTPUT: «X::AdHoc: 2017-09-10T11:56:05.477237ZWELP‼»X::AdHoc: 2017-09-10T11:56:05.477237ZWELP‼
X::AdHoc: 2026-07-28T15:17:56.077507ZWELP‼
Any:
All three differ. Needs a human.
Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.
sub f() { fail }; my $v = f; say $v.handled; # OUTPUT: «False»False
Documentation, Rakudo and Raku++ all agree.
sub f() { fail }
my $v = f;
$v.handled = True;
say $v.handled; # OUTPUT: «True»True
Documentation, Rakudo and Raku++ all agree.
sub failer() { fail };
my $failure = failer;
my $ex = $failure.exception;
put "$ex.^name(): $ex";
# OUTPUT: «X::AdHoc: Failed»X::AdHoc: Failed
Documentation, Rakudo and Raku++ all agree.
my $num1 = '♥'.Int; # $num1 now contains a Failure object, which may not be desirable
Not executed: the documentation states no expected output for this example.
my $num2 = '♥'.Int.self; # .self method call on Failure causes an exception to be thrown
Not executed: the documentation states no expected output for this example.
my $num3 = '42'.Int.self; # Int type has a .self method, so here $num3 has `42` in it
Not executed: the documentation states no expected output for this example.
(my $stuff = '♥'.Int).so; say $stuff.self; # OUTPUT: «(HANDLED) Cannot convert string to number…» # Here, Failure is handled, so .self just returns it as is
(HANDLED) Cannot convert string to number…(HANDLED) Cannot convert string to number: base-10 number must begin with valid digits or '.' in '<HERE>♥' (indicated by <HERE>)
in block <unit> at -e line 1
exception
handled True
message Cannot convert string to number: base-10 number must begin with valid digits or '.' in '♥'
All three differ. Needs a human.
Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.
sub f() { fail };
my $v = f;
say $v.handled; # OUTPUT: «False»
say $v.Bool; # OUTPUT: «False»
say $v.handled; # OUTPUT: «True»False
False
True
Documentation, Rakudo and Raku++ all agree.
sub f() { fail };
my $v = f;
say $v.handled; # OUTPUT: «False»
say $v.defined; # OUTPUT: «False»
say $v.handled; # OUTPUT: «True»False
False
True
Documentation, Rakudo and Raku++ all agree.
# A custom exception defined
class ForbiddenDirectory is Exception {
has Str $.name;Not executed: the documentation states no expected output for this example.
method message { "This directory is forbidden: '$!name'" }
}Not executed: the documentation states no expected output for this example.
sub copy-directory-tree ($dir) {
# We don't allow for non-directories to be copied
fail "$dir is not a directory" if !$dir.IO.d;
# We don't allow 'foo' directory to be copied too
fail ForbiddenDirectory.new(:name($dir)) if $dir eq 'foo';
# or above can be written in method form as:
# ForbiddenDirectory.new(:name($dir)).fail if $dir eq 'foo';
# Do some actual copying here
...
}Not executed: the documentation states no expected output for this example.
# A Failure with X::AdHoc exception object is returned and
# assigned, so no throwing Would be thrown without an assignment
my $result = copy-directory-tree("cat.jpg");
say $result.exception; # OUTPUT: «cat.jpg is not a directory»Neither engine can run this in isolation — the example depends on context from the surrounding text.
# A Failure with a custom Exception object is returned
$result = copy-directory-tree('foo');
say $result.exception; # OUTPUT: «This directory is forbidden: 'foo'»Neither engine can run this in isolation — the example depends on context from the surrounding text.
sub re-fail {
my $x = +"a";
unless $x.defined {
$x.handled = True;
say "Something has failed in \$x ", $x.^name;
# OUTPUT: «Something has failed in $x Failure»
fail($x);
return $x;
}
}
my $x = re-fail;
say $x.handled; # OUTPUT: «False»Something has failed in $x Failure
False
Documentation, Rakudo and Raku++ all agree.