Draft 3 of RFC 88 version 2.

2000-08-19 Thread Tony Olekshy

=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 

Re: Draft 3 of RFC 88 version 2.

2000-08-19 Thread Dave Rolsky

On Sat, 19 Aug 2000, Tony Olekshy wrote:

  die
 
 If argument isa "Exception", raise it as the new exception and
 die in the fashion that Perl 5 does.
 
 If argument is a string, wrap it in a new Error object, setting
 the message ivar to the given string, and raise that instead.

Actually, the Perl5 die takes a list as its argument and does join '', @_
to it to make the actual error message.

 If argument is anything else, raise a run-time exception.

So this probably shouldn't be the case.


/*==
www.urth.org
We await the New Sun
==*/




Re: Draft 3 of RFC 88 version 2.

2000-08-19 Thread Peter Scott

At 09:22 PM 8/19/00 -0500, Dave Rolsky wrote:
On Sat, 19 Aug 2000, Tony Olekshy wrote:

   die
 
  If argument isa "Exception", raise it as the new exception and
  die in the fashion that Perl 5 does.
 
  If argument is a string, wrap it in a new Error object, setting
  the message ivar to the given string, and raise that instead.

Actually, the Perl5 die takes a list as its argument and does join '', @_
to it to make the actual error message.

  If argument is anything else, raise a run-time exception.

So this probably shouldn't be the case.

This sounds alright; there's something very self-defeating about raising a 
run-time exception from dying badly, if you see what I mean.

So the third case goes and the second one becomes, args are stringified and 
joined on '', etc.

--
Peter Scott
Pacific Systems Design Technologies




Re: Draft 3 of RFC 88 version 2.

2000-08-19 Thread Tony Olekshy

Peter Scott wrote:

 Dave Rolsky wrote:
 
  Tony Olekshy wrote:
  
die
  
   If argument isa "Exception", raise it as the new
   exception and die in the fashion that Perl 5 does.
  
   If argument is a string, wrap it in a new Error
   object, setting the message ivar to the given string,
   and raise that instead.
 
  Actually, the Perl5 die takes a list as its argument and
  does join '', @_ to it to make the actual error message.
 
   If argument is anything else, raise a run-time
   exception.
 
  So this probably shouldn't be the case.

 This sounds alright; there's something very self-defeating
 about raising a run-time exception from dying badly, if you
 see what I mean.

Yes!  That's why v1 of RFC 88 didn't do that.  Thanks, Dave.

 So the third case goes and the second one becomes, args are
 stringified and joined on '', etc.

It now reads:

If passed a single argument that isa "Exception", raise it as
the new exception and die in the fashion that Perl 5 does.

Otherwise, the arguments are stringified and joined with C''
(as in Perl 5), the resulting string is wrapped up in a new
Exception object (setting the message ivar to said string),
and the new Exception object is raised.

Yours, c, Tony Olekshy.