Re: [RFC] Exceptions addition for the guide.

2000-04-09 Thread Matt Sergeant

On Sat, 8 Apr 2000, Autarch wrote:

 On Sat, 8 Apr 2000, Matt Sergeant wrote:
 
  I've written a short document on exception handling for the guide, even
  though it's not particularly mod_perl specific, Stas thinks it would be a
  good addition. Take a look at it, and let me know if there is anything you
  would change before it's added:
  
  http://modperl.sergeant.org/guide/exceptions.html
 
 This is a good tutorial.  You might want to take a look at some exception
 code I wrote (ftp://ftp.urth.org/pub/, grab the Exception and StackTrace
 tar balls) that lets you declare all your exception types via 'use'
 statements.  I think its a bit cleaner than the AUTOLOAD method you
 propose as it can catch typos later on.  Plus it lets you create actual
 class hierarchies for your exceptions, which could be nice if you want to
 create exception classes that do more stuff and then inherit from them.

Right, the intention isn't to provide the perfect exceptions system, but
to give enough of a grounding in 5.005+ exception handling to build
on. I'll add a bunch of URL's (for Error, Try and Exception modules) to a
SEE ALSO section at the end.

-- 
Matt/

Fastnet Software Ltd. High Performance Web Specialists
Providing mod_perl, XML, Sybase and Oracle solutions
Email for training and consultancy availability.
http://sergeant.org http://xml.sergeant.org




[RFC] Exceptions addition to the guide

2000-04-09 Thread Matt Sergeant

This is the 2nd attempt, at Stas' request I'm pasting the whole thing
here so you can reply and/or edit.

=head1 Exception Handling for mod_perl

Provided here are some guidelines for Sclean(er) exception handling
for mod_perl usage, although the technique presented here applies to
all of your perl programming.

The reasoning behind this document is the current broken status of
C$SIG{__DIE__} in the perl core - see both the perl5-porters and
mod_perl mailing list archives for details on this discussion.

=head1 Trapping Exceptions in Perl

To trap an exception in Perl we use the Ceval{} construct. Many
people initially make the mistake that this is the same as the Ceval
EXPR construct, which compiles and executes code at run time, but
that's not the case. Ceval{} compiles at compile time, just like the
rest of your code, and has next to zero run-time penalty.

When in an eval block, if the code executing die()'s for some reason,
rather than terminating your code, the exception is Icaught and the
program is allowed to examine that exception and make decisions based
on it. The full construct looks like this:

eval 
{
# Some code here
}; # Note important semi-colon there
if ($@) # $@ contains the exception that was thrown
{
# Do something with the exception
}
else # optional
{
# No exception was thrown
}

Most of the time when you see these exception handlers there is no else
block, because it tends to be OK if the code didn't throw an exception.

=head1 Alternative Exception Handling Techniques

An often suggested method for handling global exceptions in mod_perl,
and other perl programs in general, is a B__DIE__ handler, which can
be setup by either assigning a function name as a string to
C$SIG{__DIE__} (not particularly recommended) or assigning a code-ref
to C$SIG{__DIE__}, the usual way of doing so is to use an anonymous
sub:

$SIG{__DIE__} = sub { print "Eek - we died with:\n", $_[0]; };

The current problem with this is that C$SIG{__DIE__} is a global
setting in your script, so while you can potentially hide away your
exceptions in some external module, the execution of C$SIG{__DIE__}
is fairly magical, and interferes not just with your code, but with all
code in every module you import. Beyond the magic involved,
C$SIG{__DIE__} actually interferes with perl's normal exception
handling mechanism, the Ceval{} construct. Witness:

$SIG{__DIE__} = sub { print "handler\n"; };

eval {
print "In eval\n";
die "Failed for some reason\n";
};
if ($@) {
print "Caught exception: $@";
}

The code unfortunately prints out:

In eval
handler

Which isn't quite what you would expect, especially if that
C$SIG{__DIE__} handler is hidden away deep in some other module that
you didn't know about. There are work arounds however. One is to
localise C$SIG{__DIE__} in every exception trap you write:

eval {
local $SIG{__DIE__};
...
};

Obviously this just doesn't scale - you don't want to be doing that for
every exception trap in your code, and it's a slow down. A second work
around is to check in your handler if you are trying to catch this
exception:

$SIG{__DIE__} = sub {
die $_[0] if $^S;
print "handler\n";
};

However this won't work under Apache::Registry - you're always in an
eval block there!

My personal solution is to warn people about this danger of
C$SIG{__DIE__} and inform them of better ways to code. This is my
attempt at that.

=head1 Better Exception Handling

The Ceval{} construct in itself is a fairly weak way to handle
exceptions as strings. There's no way to pass more information in your
exception, so you have to handle your exception in more than one place
- at the location the error occured, in order to construct a sensible
error message, and again in your exception handler to deconstruct that
string into something meaningful (unless of course all you want your
exception handler to do is dump the error to the browser).

A little known fact about exceptions in perl 5.005 is that you can call
die with an object. The exception handler receives that object in $@.
This is how I always handle exceptions now, as it provides an extremely
flexible and scaleable exceptions solution.

=head2 A Little Housekeeping

First though, before we delve into the details, a little housekeeping
is in order. Most, if not all, mod_perl programs consist of a main
routine that is entered, and then dispatches itself to a routine
depending on the parameters passed and/or the form values. In a normal
C program this is your main() function, in a mod_perl handler this is
your handler() function/method.

In order for you to be able to use exception handling to it's best
extent you need to change your script to have some sort of global
exception 

Re: [RFC] Exceptions addition to the guide

2000-04-09 Thread Autarch

On Sun, 9 Apr 2000, Matt Sergeant wrote:

 For similar exception handling techniques, see the Try module, the
 Exception module and the Error module, all on CPAN.

There is no Exception module on CPAN?  If you're referring to my code,
it's not yet on CPAN because I don't think I can justify attempting to
take that namespace especially in light of the fact there eventually
will probably be exceptions in Perl itself.

If you're referring to Peter Seibel's Exceptions module, that module
is totally non-functional with modern Perl and has been superseded by
Graham Barr's Error module.

   LError - Graham Barr's excellent OO try/catch/finally module.
   LExceptions - Another exceptions module.
   LTry - Tony Olekshy's. Adds an unwind stack. Not on CPAN (yet?).

See my above comment about the Exceptions module.  I wouldn't mind
being mentioned here.  You could link to the FTP site I mentioned
before (ftp.urth.org/pub).  Eventually I may come up with a suitable
name and put it on CPAN.


-dave

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




[RFC] Exceptions addition for the guide.

2000-04-08 Thread Matt Sergeant

I've written a short document on exception handling for the guide, even
though it's not particularly mod_perl specific, Stas thinks it would be a
good addition. Take a look at it, and let me know if there is anything you
would change before it's added:

http://modperl.sergeant.org/guide/exceptions.html

-- 
Matt/

Fastnet Software Ltd. High Performance Web Specialists
Providing mod_perl, XML, Sybase and Oracle solutions
Email for training and consultancy availability.
http://sergeant.org http://xml.sergeant.org




Re: [RFC] Exceptions addition for the guide.

2000-04-08 Thread Autarch

On Sat, 8 Apr 2000, Matt Sergeant wrote:

 I've written a short document on exception handling for the guide, even
 though it's not particularly mod_perl specific, Stas thinks it would be a
 good addition. Take a look at it, and let me know if there is anything you
 would change before it's added:
 
 http://modperl.sergeant.org/guide/exceptions.html

This is a good tutorial.  You might want to take a look at some exception
code I wrote (ftp://ftp.urth.org/pub/, grab the Exception and StackTrace
tar balls) that lets you declare all your exception types via 'use'
statements.  I think its a bit cleaner than the AUTOLOAD method you
propose as it can catch typos later on.  Plus it lets you create actual
class hierarchies for your exceptions, which could be nice if you want to
create exception classes that do more stuff and then inherit from them.


-dave

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




Re: [RFC] Exceptions addition for the guide.

2000-04-08 Thread Jeff Beard



Also, checkout Graham Barr's Error.pm for an OO styled "try, throw, catch"
model. Really nice for a complete OO Perl design, IMHO.

--Jeff
 

The one
I use is a customized version but it's basically the OO "try, throw,
catch" model that I've seen in other languages. 


On Sat, 8 Apr 2000, Autarch wrote:

 N; charset=US-ASCII
 X-Spam-Rating: locus.apache.org 1.6.2 0/1000/N
 Status: U
 
 On Sat, 8 Apr 2000, Matt Sergeant wrote:
 
  I've written a short document on exception handling for the guide, even
  though it's not particularly mod_perl specific, Stas thinks it would be a
  good addition. Take a look at it, and let me know if there is anything you
  would change before it's added:
  
  http://modperl.sergeant.org/guide/exceptions.html
 
 This is a good tutorial.  You might want to take a look at some exception
 code I wrote (ftp://ftp.urth.org/pub/, grab the Exception and StackTrace
 tar balls) that lets you declare all your exception types via 'use'
 statements.  I think its a bit cleaner than the AUTOLOAD method you
 propose as it can catch typos later on.  Plus it lets you create actual
 class hierarchies for your exceptions, which could be nice if you want to
 create exception classes that do more stuff and then inherit from them.
 
 
 -dave0