Rules / Types, classes & roles / exception

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‼␤»
Documentation
X::AdHoc: 2017-09-10T11:56:05.477237ZWELP‼
Rakudo
X::AdHoc: 2026-07-28T15:17:56.077507ZWELP‼
Raku++
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␤»
Output
False

Documentation, Rakudo and Raku++ all agree.

sub f() { fail }
my $v = f;
$v.handled = True;
say $v.handled; # OUTPUT: «True␤»
Output
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␤»
Output
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
Documentation
(HANDLED) Cannot convert string to number…
Rakudo
(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

Raku++
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␤»
Output
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␤»
Output
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␤»
Output
Something has failed in $x Failure
False

Documentation, Rakudo and Raku++ all agree.