=head1 TITLE
Structured Exception/Error Handling Mechanism
=head1 VERSION
Maintainer: Tony Olekshy [EMAIL PROTECTED]
Date: 19 Aug 2000
Version: 2 (Draft 3)
Mailing List: [EMAIL PROTECTED]
Number: 88
=head1 DRAFT STATUS
This redaction has been modified to reflect Peter Scott's comments
through 2000-08-18.
Areas of development of this document which are not yet complete as
of this draft are annotated with the -- glyph. This version is not
intended to be the final redaction of this RFC, as there remains
opportunity to enhance the focus and clarity of this document to
the benefit of the reviewers hereto.
The inclusion of a definitions section for terms like propagate,
unwind, exception, and error is under consideration.
This RFC needs to better explain the purpose behind factoring Error
from Exception, an to more clearly explain the matter of RFC 80.
Production editing and spell checking have not been done yet.
=head1 ABSTRACT
"The Encyclopedia of Software Engineering" [ESE-1994] says (p.847):
Inevitably, no matter how carefully a programmer behaves when
writing a program and no matter how thoroughly its verification
is carried out, errors remain in the program and program
excecution may result in a failure. [...] The programming
laguage may provide a framework for detecting and then handling
faults, so that the program either fails gracefully or continues
to work after some remedial action has been taken to recover
from the error. Such a linguistic framework is usually called
exception handling.
This RFC describes a collection of changes and additions to Perl,
which together support built-in base classes for Exception and
Error objects, and exception and error handling code like this:
exception 'Error::DB';
try {
throw Error::DB "a message", tag = "ABC.1234", ... ;
}
catch Error::DB { ... }
catch Error::DB, Error:IO { ... }
catch $@-{message} =~ /divide by 0/ { ... }
catch { ... }
finally { ... }
Any exceptions that are raised within an enclosing try, catch, or
finally block, where the enclosing block can be located anywhere up
the subroutine call stack, are trapped and processed according to
the semantics described in this RFC.
The new built-in Error base class is designed to be used by Perl for
raising exceptions for failed operators or functions, but this RFC
can be used with the Exception and Error base classes whether or not
that happens.
Readers who are not familiar with the technique of using exception
handling to handle errors should refer to the CONVERSION section
of this document first.
=head1 DESCRIPTION
exception 'Error::App::DB::Foo';
Makes Error::App::DB::Foo into a class that inherits from the
built-in Exception class.
If the given name matches /::/, something like this happens:
@Error::App::DB::Foo::ISA = 'Error::App::DB';
and all non-existent parent classes are automatically created as
inheriting from their parent, or Exception in the tail case. If
a parent class is found to exist and not inherit from Exception,
a run-time error exception is raised.
If the given name does not match /::/ (say it's just 'Success'),
this happens instead:
@Success::ISA = 'Exception';
This means that every exception class isa Exception, even if
Exception:: is not used at the beginning of the class name.
The exception function can also take optional arguments, along
the lines of
exception 'Error_DB', isa = "Error::App";
which results in something like
@Error_DB::ISA = 'Error::App';
Other options may possibly be given to Cexception to control
things like the raise-time stack traceback.
throw Error::DB "a message", tag = "ABC.1234", ... ;
Throw is both a class and an instance method of the build-in
Exception class. The indirect object syntax is used to make the
throw imperitive. As a class method, it is syntactic sugar for:
die Error::DB-new(
message = "a message", tag = "ABC.1234", ...);
As an instance method it is syntactic sugar for copying over
any values given as arguments, and then effecting Cdie $self.
This allows Cthrow $@ to be used to re-raise exceptions.
Note that a derived class can override its constructor to
preprocess the optional arguments, so that (for example) tags
are parsed out of the message, which allows something like this
to work for developers who prefer it (such as the author):
throw MyError "ABC.1234: A message.";
This also illustrates why the message is a required argument
to the throw method. It should not have to be more complicated
than that to raise an exception of a given type with a given
annotation, in common use. One should not have to always add
"message =" just for that.
try { ... } catch EXPR { ... } finally { ... }
A try