DRAFT: Synopsis 32: Setting Library - Exceptions
Created: 26 Feb 2009
Last Modified: 28 Dec 2013 Version: 27
The document is a draft.
All built-in exceptions save for the base class Exception
live in the X::
namespace.
Generally error classes are supposed to provide the objects involved with the error, and only convert them to a string form when producing the error message. This does not apply to compile errors that involve types which have not been fully composed yet; in that case just the name of the incomplete type is included in the exception object.
Names of error classes should describe the problem in some way, or at least mention the operation that went wrong. If an error can only occur in relation to a certain type, the error types should be under X::ThatType::
.
All built-in exceptions inherit from Exception
, which provides some basic behavior: storing a backtrace and providing an interface for the backtrace printer.
class Exception { has $.backtrace; method message() { ... } # an actual stub method gist { "$.message\n$.backtrace" } method throw() { } method fail() { } method resumable() { } method resume() { } }
All direct subclasses are supposed to override method message
.
role X::OS { has $.os-error }
for all errors that are triggered by some error reported by the operating system (failed IO, system calls, fork, memory allocation).
role X::IO does X::OS { }
For IO related errors
Thrown when a file rename fails. TODO: maybe unify with X::IO::Copy?
my class X::IO::Rename does X::IO is Exception { has $.from; has $.to; method message() { "Failed to rename '$.from' to '$.to': $.os-error" } }
Thrown when a file copy operation fails
my class X::IO::Copy does X::IO is Exception { has $.from; has $.to; method message() { "Failed to copy '$.from' to '$.to': $.os-error" } }
Thrown when an mkdir
operation fails.
my class X::IO::Mkdir does X::IO is Exception { has $.path; has $.mode; method message() { "Failed to create directory '$.path' with mode '0o{$.mode.fmt("%03o")}': $.os-error" } }
Thrown when a chdir
fails
my class X::IO::Chdir does X::IO is Exception { has $.path; method message() { "Failed to change the working directory to '$.path': $.os-error" } }
Thrown when a dir()
fails
my class X::IO::Dir does X::IO is Exception { has $.path; method message() { "Failed to get the directory contents of '$.path': $.os-error" } }
Thrown when unable to determine the current directory.
my class X::IO::Cwd does X::IO is Exception { method message() { "Failed to get the working directory: $.os-error" } }
Thrown when rmdir
fails.
my class X::IO::Rmdir does X::IO is Exception { has $.path; method message() { "Failed to remove the directory '$.path': $.os-error" } }
Thrown when unlink
fails.
my class X::IO::Unlink does X::IO is Exception { has $.path; method message() { "Failed to remove the file '$.path': $.os-error" } }
Thrown when chmod
fails.
my class X::IO::Chmod does X::IO is Exception { has $.path; has $.mode; method message() { "Failed to set the mode of '$.path' to '0o{$.mode.fmt("%03o")}': $.os-error" } }
class X::NYI is Exception { has $.feature; method message() { "$.feature is not yet implemented. Sorry. " } }
For errors that stem from incomplete implementations of the Perl 6 language. A full Perl 6.0 implementation should not throw such errors.
class X::AdHoc is Exception { has $.payload handles <Str Numeric>; method message() { $.payload.Str } }
If you call &die
with non-Exception
arguments, what the user finds in his $!
variables is an object of type X::AdHoc
.
So &die
could be written as
multi sub die(Exception $e) is hidden-from-backtrace { $e.throw } multi sub die($payload) is hidden-from-backtrace { X::AdHoc.new(:$payload).throw; }
role X::Comp { has $.filename; has $.line; has $.column; }
For errors that arise from compiling code. Note that in this case the backtrace shows how the compilation was triggered (through use SomeModule;
, EVAL
s etc.). The actual location of the error does not appear in the backtrace, but rather in the attributes defined in this role.
For exceptions that can occur both at run time and at compile time, the base exception type should not do X::Comp
, but it should be mixed in into the exception object when thrown at compile time.
Thrown when a placeholder variable is used in a block that does not allow a signature (for example class A { $^foo }
.
my class X::Placeholder::Block does X::Comp { has $.placeholder; method message() { "Placeholder variable $.placeholder may not be used here because the surrounding block takes no signature"; } }
Thrown when a placeholder variable is used in the mainline, ie outside of any explicit block.
my class X::Placeholder::Mainline is X::Placeholder::Block { method message() { "Cannot use placeholder parameter $.placeholder in the mainline" } }
Thrown when a symbol is redeclared
my class X::Redeclaration does X::Comp { has $.symbol; has $.postfix = ''; has $.what = 'symbol'; method message() { "Redeclaration of $.what $.symbol$.postfix"; } }
Occurs when a symbol is being referenced that needs to be declared, but isn't.
my class X::Undeclared does X::Comp { has $.what = 'Variable'; has $.symbol; method message() { "$.what $.symbol is not declared"; } }
Thrown when an undeclared attribute is being referenced.
my class X::Attribute::Undeclared is X::Undeclared { has $.package-kind; has $.package-name; method message() { "Attribute $.name not declared in $.package-kind $.package-name"; } }
Thrown when multiple phasers of the same type occur in a block, but only one is allowed (for example CATCH
or CONTROL
).
my class X::Phaser::Multiple does X::Comp { has $.block; method message() { "Only one $.block block is allowed" } }
Thrown when a parameter has a default, but isn't allowed to have one, for example on mandatory parameters.
my class X::Parameter::Default does X::Comp { has $.how; has $.parameter; method message() { $.parameter ?? "Cannot put default on $.how parameter $.parameter" !! "Cannot put default on anonymous $.how parameter"; } }
Thrown when the user tries to use a placeholder as a formal parameter. (Usually :$foo
misspelled as $:foo
).
my class X::Parameter::Placeholder does X::Comp { has $.parameter; has $.right; method message() { "In signature parameter, placeholder variables like $.parameter are illegal\n" ~ "you probably meant a named parameter: '$.right'"; } }
Thrown when an illegal twigil is used in a formal parameter.
my class X::Parameter::Twigil does X::Comp { has $.parameter; has $.twigil; method message() { "In signature parameter $.parameter, it is illegal to use the $.twigil twigil"; } }
Thrown for multiple prefix type constraints like Int Str $x
.
my class X::Parameter::MultipleTypeConstraints does X::Comp { has $.parameter; method message() { qq[{"Parameter $.parameter" || 'A parameter'} may only have one prefix type constraint]; } }
Thrown when parameters are listed in a signature in the wrong order (for example optional before mandatory parameters).
my class X::Parameter::WrongOrder does X::Comp { has $.misplaced; has $.parameter; has $.after; method message() { "Cannot put $.misplaced parameter $.parameter after $.after parameters"; } }
Thrown when multiple named parameters have the same name.
my class X::Signature::NameClash does X::Comp { has $.name; method message() { "Name $.name used for more than one named parameter"; } }
Thrown when attempting to call a private method outside the current class or role without a fitting trust relation.
my class X::Method::Private::Permission does X::Comp { has $.method; has $.source-package; has $.calling-package; method message() { "Cannot call private method '$.method' on package $.source-package because it does not trust $.calling-package"; } }
Thrown when attempting to call a method on something else than self
without fully qualifying the class.
my class X::Method::Private::Unqualified does X::Comp { has $.method; method message() { "Private method call to $.method must be fully qualified with the package containing the method"; } }
Thrown when trying to bind to a natively typed variable TODO: inherit from X::Bind?
my class X::Bind::NativeType does X::Comp { has $.name; method message() { "Cannot bind to natively typed variable '$.name'; use assignment instead' } }
Thrown when trying to declare an attribute inside a package which doesn't support attributes.
my class X::Attribute::Package does X::Comp { has $.package-kind; method message() { "A $.package-kind cannot have attributes" } }
Thrown when an attribute is declared where it does not make sense (for example in the mainline)
my class X::Attribute::NoPackage does X::Comp { method message() { "You cannot declare an attribute here; maybe you'd like a class or a role?" } }
Thrown when a value must be known at compile time, but is not.
my class X::Value::Dynamic does X::Comp { has $.what; method message() { "$.what value must be known at compile time" } }
Thrown when a declaration does not harmonize with the declared scope (for example has sub foo() { }
.
my class X::Declaration::Scope does X::Comp { has $.scope; has $.declaration; method message() { "Cannot use '$.scope' with $.declaration declaration" } }
Thrown when a multi is declared with an incompatible scope, for example our multi sub
.
my class X::Declaration::Scope::Multi is X::Declaration::Scope { method message() { "Cannot use '$.scope' with individual multi candidates. Please declare an {$.scope}-scoped proto instead"; } }
Thrown when an anonymous multi is being declared.
my class X::Anon::Multi does X::Comp { has $.multiness; has $.routine-type = 'routine'; method message() { "Cannot put $.multiness on anonymous $.routine-type" } }
Thrown when trying to augment an anonymous package.
my class X::Anon::Augment does X::Comp { has $.package-kind; method message() { "Cannot augment anonymous $.package-kind" } }
Thrown when trying to augment a type which doesn't exist.
my class X::Augment::NoSuchType does X::Comp { has $.package-kind; has $.package; method message() { "You tried to augment $.package-kind $.package, but it does not exist" } }
Thrown at CHECK
time when there are packages stubbed but not later defined.
my class X::Package::Stubbed does X::Comp { has @.packages; # TODO: suppress display of line number method message() { "The following packages were stubbed but not defined:\n " ~ @.packages.join("\n "); } }
Thrown when trying to inherit from a type that does not support inheritance (like a package or an enum).
my class X::Inheritance::Unsupported does X::Comp { # note that this exception is thrown before the child type object # has been composed, so it's useless to carry it around. Use the # name instead. has $.child-typename; has $.parent; method message { $.child-typename ~ ' cannot inherit from ' ~ $.parent.^name ~ ' because it is not inheritable'; } }
Note that the distinction between general compile-time errors and syntax errors is somewhat blurry and arbitrary.
role X::Syntax does X::Comp { }
Common role for all syntax errors.
Thrown when obsolete (mostly Perl 5) syntax is detected.
role X::Syntax::Obsolete does X::Syntax { has $.old; has $.replacement; # cannot call it 'new', # would collide with constructor has $.when = 'in Perl 6'; method message() { "Unsupported use of $.old; $.when please use $.replacement"; } }
Thrown when a name component is empty, but shouldn't (for example use ::;
).
my class X::Syntax::Name::Null does X::Syntax { method message() { 'Name component may not be null'; } }
Thrown when an unless
clause is followed by an else
clause.
my class X::Syntax::UnlessElse does X::Syntax { method message() { '"unless" does not take "else", please rewrite using "if"' } }
Thrown when a syntax is used which is reserved for future expansion.
my class X::Syntax::Reserved does X::Syntax { has $.reserved; has $.instead = ''; method message() { "The $.reserved is reserved$.instead" } }
Thrown when some piece of syntax is clearly Perl 5, not Perl 6.
my class X::Syntax::P5 does X::Syntax { method message() { 'This appears to be Perl 5 code' } }
Thrown when a negated pair has a value, for example :!foo($val)
.
my class X::Syntax::NegatedPair does X::Syntax { has $.key; method message() { "Argument not allowed on negated pair with keys '$.key'" } }
Thrown on my $0
and the likes.
my class X::Syntax::Variable::Numeric does X::Syntax { has $.what = 'variable'; method message() { "Cannot declare a numeric $.what" } }
Thrown on my $<foo>
and the likes.
my class X::Syntax::Variable::Match does X::Syntax { method message() { 'Cannot declare a match variable' } }
Thrown on my $:foo
and the likes
my class X::Syntax::Variable::Twigil does X::Syntax { has $.twigil; has $.scope; method message() { "Cannot use $.twigil twigil on $.scope variable" } }
Thrown on my $::($name);
and similar constructs.
my class X::Syntax::Variable::IndirectDeclaration does X::Syntax { method message() { 'Cannot declare a variable by indirect name (use a hash instead?)' } }
Thrown when augment
is used without use MONKEY-TYPING
.
my class X::Syntax::Augment::WithoutMonkeyTyping does X::Syntax { method message() { "augment not allowed without 'use MONKEY-TYPING'" }; }
Thrown when trying to augment a role.
my class X::Syntax::Augment::Role does X::Syntax { has $.role-name; method message() { "Cannot augment role $.role-name, since roles are immutable" }; }
Occurs when a placeholder is used in a block that already has a signature attached. TODO: report the placeholder variables.
my class X::Signature::Placeholder does X::Syntax { method message() { 'Placeholder variable cannot override existing signature'; } }
Thrown when #`
is encountered and it is not followed by an opening bracket.
my class X::Syntax::Comment::Embedded does X::Syntax { method message() { "Opening bracket required for #` comment" } }
Thrown when =begin
is encountered and no identifier comes after it.
my class X::Syntax::Pod::BeginWithoutIdentifier does X::Syntax does X::Pod { method message() { '=begin must be followed by an identifier; (did you mean "=begin pod"?)' } }
Thrown when =begin identifier
is parsed without the matching =end identifier
.
my class X::Syntax::Pod::BeginWithoutEnd does X::Syntax does X::Pod { method message() { '=begin without matching =end' } }
The most general syntax error, if no more specific error message can be given.
my class X::Syntax::Confused does X::Syntax { method message() { 'Confused' } }
Thrown when a parsed construct is malformed.
my class X::Syntax::Malformed does X::Syntax { has $.what; method message() { "Malformed $.what" } }
Thrown when the previous piece of syntax requires the existence of another piece of syntax, and that second piece is missing.
my class X::Syntax::Missing does X::Syntax { has $.what; method message() { "Missing $.what" } }
Thrown when a sigil without a following name is encountered in a place where this is not allowed.
my class X::Syntax::SigilWithoutName does X::Syntax { method message() { 'Non-declarative sigil is missing its name' } }
Thrown when self
is referenced in a place where no invocant is available.
my class X::Syntax::Self::WithoutObject does X::Syntax { method message() { "'self' used where no object is available" } }
Thrown when a $.foo
style virtual call appears before an object is fully constructed, for example has $.a = $.b;
.
my class X::Syntax::VirtualCall does X::Syntax { has $.call; method message() { "Virtual call $.call may not be used on partially constructed objects" } }
Thrown when $.foo
style calls are used where no invocant is available.
my class X::Syntax::NoSelf does X::Syntax { has $.variable; method message() { "Variable $.variable used where no 'self' is available" } }
Thrown when the radix of a radix number is larger not allowed, like :1<1>
or :42<ouch>
.
my class X::Syntax::Number::RadixOutOfRange does X::Syntax { has $.radix; method message() { "Radix $.radix out of range (allowed: 2..36)" } }
Thrown when an unrecognized or illegal regex adverb is encountered (for example rx:g/a/
).
my class X::Syntax::Regex::Adverb does X::Syntax { has $.adverb; has $.construct; method message() { "Adverb $.adverb not allowed on $.construct" } }
Thrown when a stand alone quantifier in a regex is encountered (for example / * /
).
my class X::Syntax::Regex::SolitaryQuantifier does X::Syntax { method message { 'Quantifier quantifies nothing' } }
Thrown when a backslash-variable is declared without initialization assignment.
my class X::Syntax::Term::MissingInitializer does X::Syntax { method message { "Term definition requires an initializer" } }
Thrown when a circumfix operator is defined without separator between opening and closing terminators.
my class X::Syntax::AddCategorial::MissingSeparator does X::Syntax { has $.opname; method message { "Unable to identify both starter and stopper from $.opname\nPerhaps you forgot to separate them with whitespace?" } }
Thrown when the invocant in a signature is anywhere else than after the first parameter.
my class X::Syntax::Signature::InvocantMarker does X::Syntax { method message() { "Can only use : as invocant marker in a signature after the first parameter" } }
Thrown when a subroutine of name category:<symbol>()
is encountered, and the category is not known.
my class X::Syntax::Extension::Category does X::Syntax { has $.category; method message() { "Cannot add tokens of category '$.category'"; } }
Thrown when the parser expects a term, but finds an infix operator.
my class X::Syntax::InfixInTermPosition does X::Syntax { has $.infix; method message() { "Preceding context expects a term, but found infix $.infix instead"; } }
role X::Pod { }
Common role for all Pod-related errors.
Thrown when the user tries to call a method that isn't there, for example 1.foo
.
TODO: should hold the actual invocation, not the type name. Currently that's due to a limit in Rakudo and Parrot.
my class X::Method::NotFound is Exception { has $.method; has $.typename; has Bool $.private = False; method message() { $.private ?? "No such private method '$.method' for invocant of type '$.typename'" !! "No such method '$.method' for invocant of type '$.typename'"; } }
Thrown when a method is call in the form $invocant.TheClass::method
if <$invocant> does not conform to TheClass
my class X::Method::InvalidQualifier is Exception { has $.method; has $.invocant; has $.qualifier-type; method message() { "Cannot dispatch to method $.method on {$.qualifier-type.^name} " ~ "because it is not inherited or done by {$.invocant.^name}"; } }
General error when something (for example an array index) is out of an allowed range.
my class X::OutOfRange is Exception { has $.what = 'Argument'; has $.got = '<unknown>'; has $.range = '<unknown>'; has $.comment; method message() { $.comment.defined ?? "$.what out of range. Is: $.got, should be in $.range.gist(); $.comment" !! "$.what out of range. Is: $.got, should be in $.range.gist()" } }
Thrown when a Buf
object is used as string.
my class X::Buf::AsStr is Exception { has $.method; method message() { "Cannot use a Buf as a string, but you called the $.method method on it"; } }
Thrown when an unknown template/directive is encountered by pack
or unpack
.
my class X::Buf::Pack is Exception { has $.directive; method message() { "Unrecognized directive '$.directive'"; } }
Thrown when the A
template/directive comes across a non-ASCII character.
my class X::Buf::Pack::NonASCII is Exception { has $.char; method message() { "non-ASCII character '$.char' while processing an 'A' template in pack"; } }
Thrown when trying to bind to something which isn't a valid target for binding (except for some more special cases listed below).
my class X::Bind is Exception { has $.target; method message() { $.target.defined ?? "Cannot bind to $.target" !! 'Cannot use bind operator with this left-hand side' } }
Thrown when trying to bind to a slice. TODO: inherit from X::Bind?
my class X::Bind::Slice is Exception { has $.type; method message() { "Cannot bind to {$.type.^name} slice"; } }
Thrown when trying to bind to a Zen slice, eg @a[] := (1, 2)
.
my class X::Bind::ZenSlice is X::Bind::Slice { method message() { "Cannot bind to {$.type.^name} zen slice"; } }
Thrown when trying to use infix does
(not the trait) on a type object.
my class X::Does::TypeObject is Exception { method message() { "Cannot use 'does' operator with a type object." } }
Thrown when the SomeRole($init)
syntax is used, but SomeRole does not have exactly one public attribute.
my class X::Role::Initialization is Exception { method message() { 'Can only supply an initialization value for a role if it has a single public attribute' } }
Thrown when &routine.unwrap
is called with an argument that is not a wrap handle.
my class X::Routine::Unwrap is Exception { method message() { "Cannot unwrap routine: invalid wrap handle" } }
Thrown from Mu.new
when positional arguments are passed to it.
my class X::Constructor::Positional is Exception { method message() { "Default constructor only takes named arguments" } }
Thrown when hash assignment finds a trailing hash key with a value.
my class X::Hash::Store::OddNumber is Exception { method message() { "Odd number of elements found where hash expected" } }
Thrown when the condition inside a PRE
or POST
phaser evaluate to a false value.
my class X::Phaser::PrePost is Exception { has $.phaser = 'PRE'; has $.condition; method message { my $what = $.phaser eq 'PRE' ?? 'Precondition' !! 'Postcondition'; $.condition.defined ?? "$what '$.condition.trim()' failed" !! "$what failed"; } }
Thrown (or wrapped in a Failure
) when a conversion from string to number fails.
my class X::Str::Numeric is Exception { has $.source; has $.pos; has $.reason; method source-indicator { constant marker = chr(0x23CF); join '', "in '", $.source.substr(0, $.pos), marker, $.source.substr($.pos), "' (indicated by ", marker, ")", ; } method message() { "Cannot convert string to number: $.reason $.source-indicator"; } }
Thrown when Str.match(:$x)
or m:x($x)//
is called with an type of $x
that is now allowed.
my class X::Str::Match::x is Exception { has $.got; method message() { "in Str.match, got invalid value of type {$.got.^name} for :x, must be Int or Range" } }
Thrown when a Pair passed to Str.trans
is of a type that the trans method cannot work with (regexes and types derived from Cool
are fine).
my class X::Str::Trans::IllegalKey is Exception { has $.key; method message { "in Str.trans, got illegal substitution key of type {$.key.^name} (should be a Regex or Str)" } }
Thrown when an argument to Str.trans
is not a Pair
.
my class X::Str::Trans::InvalidArg is Exception { has $.got; method message() { "Only Pair objects are allowed as arguments to Str.trans, got {$.got.^name}"; } }
Thrown when an argument to Range.new
is a Range
.
my class X::Range::InvalidArg is Exception { has $.got; method message() { "{$.got.^name} objects are not valid endpoints for Ranges"; } }
Exception type when the ...
sequence operator is being called without an explicit closure, and the sequence cannot be deduced.
my class X::Sequence::Deduction is Exception { method message() { 'Unable to deduce sequence' } }
Thrown when a control flow construct (such as next
or redo
) is called outside the dynamic scope of an enclosing construct that is supposed to catch them.
my class X::ControlFlow is Exception { has $.illegal; # something like 'next' has $.enclosing; # .... outside a loop
method message() { "$.illegal without $.enclosing" } }
Thrown when a return
is called from outside a routine.
my class X::ControlFlow::Return is X::ControlFlow { method illegal() { 'return' } method enclosing() { 'Routine' } method message() { 'Attempt to return outside of any Routine' } }
Thrown when trying to compose a type into a target type, but the composer type cannot be used for composition (roles and enums are generally OK).
my class X::Composition::NotComposable is Exception { has $.target-name; has $.composer; method message() { $.composer.^name ~ " is not composable, so $.target-name cannot compose it"; } }
Thrown when a type check fails.
my class X::TypeCheck is Exception { has $.operation; has $.got; has $.expected; method message() { "Type check failed in $.operation; expected '{$.expected.^name}' but got '{$.got.^name}'";
} }
Thrown when the type check of a binding operation fails.
TODO: figure out if we actually need that type
my class X::TypeCheck::Binding is X::TypeCheck { method operation { 'binding' } }
Thrown when a return type check fails.
TODO: figure out if we actually need that type
my class X::TypeCheck::Return is X::TypeCheck { method operation { 'returning' } method message() { "Type check failed for return value; expected '{$.expected.^name}' but got '{$.got.^name}'"; } }
Thrown when a redispatcher like nextsame
is called without being in the dynamic scope of a call that could possible redispatch.
my class X::NoDispatcher is Exception { has $.redispatcher; method message() { "$.redispatcher is not in the dynamic scope of a dispatcher"; } }
Thrown when let
or temp
or a similar localizer are used on a non-container, like temp 1 = 2
.
my class X::Localizer::NoContainer is Exception { has $.localizer; method message() { "Can only use '$.localizer' on a container"; } }
Thrown when a mixin with infix does
or but
is done with a composer that cannot be used for mixin.
my class X::Mixin::NotComposable is Exception { has $.target; has $.rolish; method message() { "Cannot mix in non-composable type {$.rolish.^name} into object of type {$.target.^name}"; } }
Thrown when a symbol is exported twice.
my class X::Export::NameClash is Exception { has $.symbol; method message() { "A symbol '$.symbol' has already been exported"; } }
Thrown when a non-DWIMy hyperop has lists of lengths that do not match.
my class X::HyperOp::NonDWIM is Exception { has &.operator; has $.left-elems; has $.right-elems; method message() { "Lists on both side of non-dwimmy hyperop of &.operator.name() are not of the same length\n" ~ "left: $.left-elems elements, right: $.right-elems elements"; } }
Thrown when Set($obj)
is called to coerce an object to a Set
, and Set
does not know how to handle an object of such type.
my class X::Set::Coerce is Exception { has $.thing; method message { "Cannot coerce object of type {$.thing.^name} to Set. To create a one-element set, pass it to the 'set' function"; } }
A common exception type for all errors related to DateTime
or Date
.
my role X::Temporal is Exception { }
Thrown when the Date
or DateTime
constructors get a string in a format which is not a valid date format.
my class X::Temporal::InvalidFormat is X::Temporal { has $.invalid-str; has $.target = 'Date'; has $.format; method message() { "Invalid $.target string '$.invalid-str'; use $.format instead"; } }
Thrown when DateTime.truncated-to
or Date.truncated-to
are called in a way that doesn't make sense.
my class X::Temporal::Truncation is X::Temporal { has $.class = 'DateTime'; has $.error; method message() { "in $.class.truncated-to: $.error"; } }
Thrown when EVAL($str, :$lang)
specifies a language that the compiler does not know how to handle.
my class X::Eval::NoSuchLang is Exception { has $.lang; method message() { "No compiler compiler available for language '$.lang'"; } }
Occurs when an attempt to coerce a Numeric
to a Real
, Num
, Int
or Rat
fails (due to a number with a nonzero imaginary part, for instance).
my class X::Numeric::Real is Exception { has $.source; has $.target; has $.reason;
method message() { "Can not convert $.source to {$.target.^name}: $.reason"; } }
Occurs when a stub (created via !!!
, or ...
with use fatal
) is executed.
my class X::StubCode is Exception { has $.message = 'Stub code executed'; }
class Failure is Mu { has Bool $.handled is rw; has $.X; # the actual exception object }
An unthrown exception, usually produce by fail()
.
(Conjecture: S04 implies that all exceptions have a $.handled
attribute. Do we actually need that?)
class Backtrace does Positional[Backtrace::Frame] { method Stringy() { ... } method full() { ... } } class Backtrace::Frame { has $.file; has $.line; has $.code; has $.subname;
method is-hidden () { ... } method is-routine() { ... } method is-setting() { ... } }
Backtrace information, typically used (but not limited to) in exceptions. Stringifies to
in '$<routine>' at line $<line>:$<filename> in '$<routine>' at line $<line>:$<filename> ...
with two leading spaces on each line.
The default stringification includes blocks and routines from user-space code, but from the setting only routines are shown [conjectural]. Routines can be hidden from the default backtrace stringification by apply the hidden-from-backtrace
trait:
sub my-die(*@msg) is hidden-from-backtrace { }
the is-hidden
method in Backtrace::Frame
returns Bool::True
for routines with that trait.
The full
method in Backtrace
provides a string representation of the backtrace that includes all available code objects, including hidden ones.
If a code object does not have a name, <anon>
is used instead of the routine name.
In case an exception does not get caught by any CATCH
or CONTROL
block, it is caught by a default handler in the setting.
This handler calls the .gist
method on the exception, prints the result, and terminates the program. The exit code is determined as $exception.?exit-code // 1
.
Moritz Lenz <[email protected]>
Authors of previous versions of this document:
Tim Nelson <[email protected]> Larry Wall <[email protected]>[ Top ] [ Index of Synopses ]