DRAFT: Synopsis 32: Setting Library - Exceptions
Moritz Lenz <moritz@faui2k.org>
Authors of previous versions of this document:
Tim Nelson <wayland@wayland.id.au>
Larry Wall <larry@wall.org>
Created: 26 Feb 2009
Last Modified: 11 February 2012
Version: 7
The document is a draft.
If you read the HTML version, it is generated from the Pod in the specs repository under https://github.com/perl6/specs/blob/master/S32-setting-library/Exception.pod so edit it there in the git repository if you would like to make changes.
All built-in exceptions save for the base class Exception
live in the X::
namespace.
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() { }
}
All 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 { }
For IO related errors
role X::NYI {
has $.feature;
}
For errors that stem from incomplete implementations of the Perl 6 language. A full Perl 6.0 implementation should not throw such errors.
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.
role X::Syntax does X::Comp { }
Common role for all syntax errors.
role X::Syntax::Obsolete does X::Syntax {
has $.ID;
has $.old;
has $.new;
has $.when = 'in Perl 6'
}
Message defaults to Unsupported use of $<old>;$<when> please use $<new>
.
role X::Syntax::BadInfx does X::Syntax {
has $.bad;
}
Message defaults to Preceding context expects a term, but found infix $<bad> instead
.
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($message) is hidden_from_backtrace {
X::AdHoc.new(:$message).throw;
}
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 termintates the program. The exit code is determined as $exception.?exit-code // 1
.