BrowserREPL-button-tip-on BrowserREPL-button-tip-off

EditButtonTip 2024-07-13

class Exception

Anomalous event capable of interrupting normal control-flow

class Exception {}
Code

All exceptions that are placed into the $! variable (or into $_ in CATCH blocks) inherit from Exception. When you call die or fail with a non-Exception argument, it is wrapped into an X::AdHoc object, which also inherits from Exception.

User-defined exception classes should inherit from Exception too, and define at least a method message.

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

Methods§

method message§

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

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.

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

method backtrace§

method backtrace(Exception:D:)
Code

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.

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

method throw§

method throw(Exception:D:)
Code

Throws the exception.

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

method resume§

method resume(Exception:D:)
Code

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

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

method rethrow§

method rethrow(Exception:D:)
Code

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

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

routine fail§

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

Exits the calling Routine and returns a Failure object wrapping the exception.

# 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;
Code

The routine form works in the same way, with an alternative syntax: fail ForbiddenWord.new(:word($word)).

method gist§

multi method gist(Exception:D:)
Code

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

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␤»
Code

method Failure§

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

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:)
Code

Throws a fatal Exception. The default exception handler prints each element of the list to $*ERR (STDERR).

die "Important reason";
Code

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 X::AdHoc exception. If $! is not .DEFINITE, X::AdHoc with string "Died" as payload will be thrown.

die will print by default the line number where it happens

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

However, that default behavior is governed at the Exception level and thus can be changed to anything we want by capturing the exception using CATCH. This can be used, for instance, to suppress line numbers.

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

sub warn§

multi warn(*@message)
Code

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 warnings but pass fatal exceptions through.

To simply print to $*ERR, please use note instead. warn should be reserved for use in threatening situations when you don't quite want to throw an exception.

warn "Warning message";
Code

Class relation diagram§

Rakudo Type Relation for Exception Exception Exception Any Any Exception->Any is