Rules / Types, classes & roles / exception

Exception Reference

Anomalous event capable of interrupting normal control-flow

What it is #

Position in the hierarchy #

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 message #

method message(Exception:D: --> Str:D)

Returns Str:D.

This is a stub that must be overwritten by subclasses, and should return the exception message. Special care should be taken that this method does not produce an exception itself.

method backtrace #

method backtrace(Exception:D:)

Returns the backtrace associated with the exception in a Backtrace object or an empty string if there is none. Only makes sense on exceptions that have been thrown at least once.

method throw #

method throw(Exception:D:)

Throws the exception.

method resume #

method resume(Exception:D:)

Resumes control flow where .throw left it when handled in a CATCH block.

method rethrow #

method rethrow(Exception:D:)

Rethrows an exception that has already been thrown at least once. This is different from throw in that it preserves the original backtrace.

routine fail #

multi  fail(Exception $e)
method fail(Exception:D:)

Exits the calling Routine and returns a Failure object wrapping the exception. The routine form works in the same way, with an alternative syntax: fail ForbiddenWord.new(:word($word)).

method gist #

multi method gist(Exception:D:)

Returns whatever the exception printer should produce for this exception. The default implementation returns message and backtrace separated by a newline.

method Failure #

method Failure(Exception:D: --> Failure:D)

Returns Failure:D.

Available as of the 2022.06 release of the Rakudo compiler. Coerces the Exception into a Failure object.

routine die #

multi  die()
multi  die(*@message)
multi  die(Exception:D $e)
method die(Exception:D:)

Throws a fatal Exception. The default exception handler prints each element of the list to $*ERR (STDERR). If the subroutine form is called without arguments, the value of $! variable is checked. If it is set to a .DEFINITE value, its value will be used as the Exception to throw if it's of type Exception, otherwise, it will be used as payload of

sub warn #

multi warn(*@message)

Throws a resumable warning exception, which is considered a control exception, and hence is invisible to most normal exception handlers. The outermost control handler will print the warning to $*ERR. After printing the warning, the exception is resumed where it was thrown. To override this behavior, catch the exception in a CONTROL block. A quietly {...} block is the opposite of a try {...} block in that it will suppress any

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.

1 doc-drift · 11 no-output · 1 ok

class Exception {}

Not executed: the documentation states no expected output for this example.

class X::YourApp::SomeError is Exception {
    method message() {
        "A YourApp-Specific error occurred: out of coffee!";
    }
}

Not executed: the documentation states no expected output for this example.

try die "Something bad happened";
if ($!) {
    say $!.message; # OUTPUT: «Something bad happened.␤»
}
Documentation
Something bad happened.
Rakudo
Something bad happened
Raku++
Something bad happened

Both engines agree; the documentation states something else. Trust the engines.

try die "Something bad happened";
with $! { .backtrace.print ; }

Not executed: the documentation states no expected output for this example.

my $exception = X::AdHoc.new;    # Totally fine
try $exception.throw;            # Throws
if ($!) { #`( some handling ) }; # Suppress the exception

Not executed: the documentation states no expected output for this example.

# For example, resume control flow for any exception
CATCH { default { .resume } }

Not executed: the documentation states no expected output for this example.

sub f() { die 'Bad' };
sub g() { f; CATCH { default { .rethrow } } };
g;
CATCH { default { say .backtrace.full } };

Not executed: the documentation states no expected output for this example.

# A custom exception defined
class ForbiddenWord is Exception {
has Str $.word;
method message { "This word is forbidden: «$!word»" }
}

sub say-word ( $word ) {
ForbiddenWord.new(:word($word)).fail if $word eq 'foo';
$word.say;
}

my $result = say-word("foo");
say $result.exception;

Not executed: the documentation states no expected output for this example.

my $e = X::AdHoc.new(payload => "This exception is pretty bad");
try $e.throw;
if ($!) { say $!.gist; };
# OUTPUT: «This exception is pretty bad
#   in block <unit> at <unknown file> line 1␤»

Not executed: the documentation states no expected output for this example.

die "Important reason";

Not executed: the documentation states no expected output for this example.

die "Dead";
# OUTPUT: «(exit code 1) Dead␤
# in block <unit> at /tmp/dead.raku line 1␤␤»

Not executed: the documentation states no expected output for this example.

CATCH {
  default {
.payload.say
  }
};
die "Dead" # OUTPUT: «Dead␤»
Output
Dead

Documentation, Rakudo and Raku++ all agree.

warn "Warning message";

Not executed: the documentation states no expected output for this example.