X::AdHoc is the type into which objects are wrapped if they are thrown as exceptions, but don't inherit from Exception.
Its benefit over returning non-Exception objects is that it gives access to all the methods from class Exception, like backtrace and rethrow.
You can obtain the original object with the payload method.
die [404, 'File not found']; # throw non-exception object } print "Got HTTP code ", $!.payload[0], # 404 " and backtrace ", $!.backtrace.Str;
Note that young code will often be prototyped using X::AdHoc and then later be revised to use more specific subtypes of Exception. As such it is usually best not to explicitly rely on receiving an X::AdHoc – in many cases using the string returned by the .message method, which all Exceptions must have, is preferable. Please note that we need to explicitly call .Str to stringify the backtrace correctly.
Methods §
method payload §
Returns the original object which was passed to die.
method Numeric §
Defined as
Converts the payload to Numeric and returns it
method from-slurpy §
Defined as
Creates a new exception from a capture and returns it. The capture will have the SlurpySentry role mixed in, so that the .message method behaves in a different when printing the message.
X::AdHoc.from-slurpy( 3, False, "Not here" ).throw }; print $!.payload.^name; # OUTPUT: «Capture+{X::AdHoc::SlurpySentry}» print $!.message; # OUTPUT: «3FalseNot here»
The SlurpySentry role joins the elements of the payload, instead of directly converting them to a string.
Type Graph §
X::AdHocRoutines supplied by class Exception §
X::AdHoc inherits from class Exception, which provides the following routines:
(Exception) method message §
Defined as:
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.
if ($!) { say $!.message; # OUTPUT: «Something bad happened.» }
(Exception) method backtrace §
Defined as:
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.
with $! { .backtrace.print ; }
(Exception) method throw §
Defined as:
Throws the exception.
try $exception.throw; # Throws if ($!) { #`( some handling ) }; # Suppress the exception
(Exception) method resume §
Defined as:
Resumes control flow where .throw left it when handled in a CATCH block.
CATCH { default { .resume } }
(Exception) method rethrow §
Defined as:
Rethrows an exception that has already been thrown at least once. This is different from throw in that it preserves the original backtrace.
sub g() { f; CATCH { default { .rethrow } } }; g; CATCH { default { say .backtrace.full } };
(Exception) routine fail §
Defined as:
method fail(Exception:D:)
Exits the calling Routine and returns a Failure object wrapping the exception.
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;
The routine form works in the same way, with an alternative syntax: fail ForbiddenWord.new(:word($word)).
(Exception) method gist §
Defined as:
Returns whatever the exception printer should produce for this exception. The default implementation returns message and backtrace separated by a newline.
try $e.throw; if ($!) { say $!.gist; }; # OUTPUT: «This exception is pretty bad # in block
(Exception) routine die §
Defined as:
multi sub die(*@message) multi sub 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 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
# OUTPUT: «(exit code 1) Dead # in block
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.
default { .payload.say } }; die "Dead" # OUTPUT: «Dead»
(Exception) sub warn §
Defined as:
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.