Re: Propogating Errors / E-Toys

2002-07-10 Thread Matt Sergeant

On Wed, 10 Jul 2002, Fran Fabrizio wrote:


 Just to confirm, the end result of Matt's slide presentation was that
 Error.pm was good, and you should use it, but you should not use the
 try/catch syntax, or at the bare minimum only catch in your outermost
 handler.  Is that correct?  We were debating this just yesterday in our
 office.

Actually my recommendation for this year's talk on exceptions is to just
use eval{}; if ($) {}. It's a little more typing, but at the end of the
day closures created by subroutine prototypes are a really bad thing (tm).

-- 
!-- Matt --
:-Get a smart net/:-




Re: Propogating Errors / E-Toys

2002-07-10 Thread Perrin Harkins

Matt Sergeant wrote:
 On Wed, 10 Jul 2002, Fran Fabrizio wrote:
Just to confirm, the end result of Matt's slide presentation was that
Error.pm was good, and you should use it, but you should not use the
try/catch syntax, or at the bare minimum only catch in your outermost
handler.  Is that correct?  We were debating this just yesterday in our
office.
 
 Actually my recommendation for this year's talk on exceptions is to just
 use eval{}; if ($) {}. It's a little more typing, but at the end of the
 day closures created by subroutine prototypes are a really bad thing (tm).

I believe he was asking if Error.pm is a good class to use for 
exceptions if you don't use the try/catch keywords.  I think it is.  It 
provides handy methods for storing attributes of the exception and 
getting stack traces, and it's easy to subclass.  You could also use 
Dave Rolsky's Exception::Class, which is pretty similar.

- Perrin




Re: Propogating Errors / E-Toys

2002-07-10 Thread Matt Sergeant

On Wed, 10 Jul 2002, Perrin Harkins wrote:

 Matt Sergeant wrote:
  On Wed, 10 Jul 2002, Fran Fabrizio wrote:
 Just to confirm, the end result of Matt's slide presentation was that
 Error.pm was good, and you should use it, but you should not use the
 try/catch syntax, or at the bare minimum only catch in your outermost
 handler.  Is that correct?  We were debating this just yesterday in our
 office.
 
  Actually my recommendation for this year's talk on exceptions is to just
  use eval{}; if ($) {}. It's a little more typing, but at the end of the
  day closures created by subroutine prototypes are a really bad thing (tm).

 I believe he was asking if Error.pm is a good class to use for
 exceptions if you don't use the try/catch keywords.  I think it is.  It
 provides handy methods for storing attributes of the exception and
 getting stack traces, and it's easy to subclass.  You could also use
 Dave Rolsky's Exception::Class, which is pretty similar.

Ah, in that case I'm recommending Dave's stuff. It's more flexible and
doesn't use that irritating -param stuff. Though I have to do a little
more research to be certain some things are possible (like turning on
stack traces globally).

-- 
!-- Matt --
:-Get a smart net/:-




Re: Propogating Errors / E-Toys

2002-07-10 Thread Dave Rolsky

On Wed, 10 Jul 2002, Matt Sergeant wrote:

 Ah, in that case I'm recommending Dave's stuff. It's more flexible and
 doesn't use that irritating -param stuff. Though I have to do a little
 more research to be certain some things are possible (like turning on
 stack traces globally).

Actually, traces are now _always_ created.  And by default they're shown
when stringifying the exception object.

To turn this off you do:

 Exception::Class::Base-Trace(0);

To turn it off for one branch of the hierarchy, do:

 My::Exception::Subclass-Trace(0);

to turn it back on for a branch below that, do:

 My::Exception::Subclass::SubSubClass-Trace(1);

I'm also planning to add some more features to it.

One is something we're using with Mason, where we create convenience subs
for throwing exceptions so we can do:

 param_error Missing 'foo' in call to new;

instead of:

 HTML::Mason::Exception::Params-throw( error = Missing 'foo' in call to new );

plus as an added bonus the first version gets compile time checking of the
sub name, versus runtime checking of the class name in the second.



-dave

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




Re: Propogating Errors / E-Toys

2002-07-09 Thread Michael Schout

Perrin Harkins wrote:
 
 We've actually discussed this on the list.  It has to do with closures. 
  Matt gave a presentation about exception handling which covers it and 
 shows a workaround.  You can see it here:
 
 http://axkit.org/docs/presentations/tpc2001/

Sorry to chime in a little late on this.

But the Exceptions slides from the page above are either misleading, 
or I am misunderstainding just what exactly leaks in Error.

The slides above show a BAD example of Error.pm as:

sub handler {
 my $r = shift;
 my $count;

 try {
 # use $count in here...
 } catch Error with {
 };
}

However, the eToys article doesnt say that this is unsafe.  What the 
eToys article says is unsafe is code with nested try blocks like this:

my $count;
try {
...
try {
 # use $count in *here*
};
};

in other words, if I understand the eToys article correctly, the leaks 
only happen if I nest a try block inside another try block.  I have 
experimented some, and it appears to me that this is in fact the case 
($count doesnt get cleaned up if there is a nested try).  But as long as
I dont nest try blocks there doesnt appear to be a leak.

Are Matt's slides misleading on this point?  Or am I missing something here?

Mike




Re: Propogating Errors / E-Toys

2002-07-09 Thread Perrin Harkins

Michael Schout wrote:

 in other words, if I understand the eToys article correctly, the leaks 
 only happen if I nest a try block inside another try block.  I have 
 experimented some, and it appears to me that this is in fact the case 
 ($count doesnt get cleaned up if there is a nested try).  But as long as
 I dont nest try blocks there doesnt appear to be a leak.


You are correct, you won't get a leak from the code in Matt's example. 
 What you will get is an unexpected persistence of the value of the 
$count variable.  It will retain its value and not be reset when you 
enter the handler sub again.

There are other problems too, like return not doing what you would 
expect when used inside a try block (it only returns from the try block).

- Perrin




Re: Propogating Errors / E-Toys

2002-07-09 Thread Matt Sergeant

On Wed, 10 Jul 2002, Michael Schout wrote:

 Perrin Harkins wrote:
 
  We've actually discussed this on the list.  It has to do with closures.
   Matt gave a presentation about exception handling which covers it and
  shows a workaround.  You can see it here:
 
  http://axkit.org/docs/presentations/tpc2001/

 Sorry to chime in a little late on this.

 But the Exceptions slides from the page above are either misleading,
 or I am misunderstainding just what exactly leaks in Error.

I didn't say leaks in my slides. That's what you're misunderstanding. It
merely creates a closure. This *can* lead to leaks, but doesn't always.

I guess at some point I aught to pick up Error::Filter again. Damn that
hard drive crash (which lost the source code I had for a source filter
version of Error.pm, which didn't create closures).

-- 
!-- Matt --
:-Get a smart net/:-




Propogating Errors / E-Toys

2002-06-30 Thread Richard Clarke

List,
Without wanting to fire up a huge thread about MVC seperation etc etc. I
just wondered if someone would share their expertise on the following
question.
Using Perrin's article on E-Toys is perhaps a good place to start. In the
Model object which performs various DB procedures, what actions were taken
if for some reason the connection to the database failed or if an SQL error
happened? Was the whole execute() block put in an eval procedure and then
a generic error page produced; Or were either per procedure evals or
Exception objects used to propogate specific errors up to the control object
so that it could display errors in the current page/view?

Richard




Re: Propogating Errors / E-Toys

2002-06-30 Thread Perrin Harkins

Richard Clarke wrote:
 Using Perrin's article on E-Toys is perhaps a good place to start. In the
 Model object which performs various DB procedures, what actions were taken
 if for some reason the connection to the database failed or if an SQL error
 happened? Was the whole execute() block put in an eval procedure and then
 a generic error page produced; Or were either per procedure evals or
 Exception objects used to propogate specific errors up to the control object
 so that it could display errors in the current page/view?

Well, naturally the answer is it depends.  Most database errors can't 
be gracefully recovered from, so we would let them propagate up.  If it 
was possible for a database error to be caused by user input (say, a 
duplicate login name) that would need to be caught and handled.  It 
would also be caught if any special cleanup of non-database resources 
was needed.

Errors that propagate up are caught by an eval wrapping the whole 
handler method which issues a rollback to the database, logs the error, 
and prints either a pretty error page or a stack trace depending on the 
current debug settings.

Here's an excerpt from the documentation I wrote for our exception base 
class.  This uses the try/catch syntax from Error.pm.

=head1 HANDLING DBI ERRORS

Since DBI errors are the most common source of exceptions in our
application, I'm giving them special treatment here.  Because we are
planning to use the RaiseError option of DBI, you can expect DBI to
die whenever it hits a problem, as opposed to returning an undef value
that you have to check for.  This means that most of the time you
don't need to do anything special for handling DBI errors.  They will
propagate up and be caught at the top level.

DBI exceptions will be propagated as instances of the Error::Simple
class.

You can catch your own exceptions without catching the DBI
exceptions by catching specific classes other than Error::Simple.

   try {
   # lookup password in Oracle
   my $sth = $dbh-prepare_cached($sql_query);
   $sth-execute($bind_value);
   if (!$sth-rows) {
   # should have matched something
   throw ESF::Error::User::BogusPassword -text $password;
   }
   $ary_ref  = $sth-fetchrow_arrayref;
   # ... etc. ...
   }
   catch ESF::Error::User::BogusPassword with {
   # handle this error
   }; # -- don't forget!

It's okay to use transactions, and to put in your C$dbh-commit
statement at the end assuming everything will work.  If DBI throws an
exception that propagates to the top without being caught, we will
automatically issue a C$dbh-rollback command.

Sometimes, you may want to catch a specific DBI error.  Be careful
when doing this, because you need to know the error number or text of
the error message in order to trap the right exception.

DBI's raise error setting will cause it to fill the text attribute of
the Error::Simple objects it throws with the message given by Oracle,
so if you want to trap errors of type ORA-172, you can do this:

   try {
   my $sth = $dbh-prepare_cached($sql_query);
   $sth-execute($bind_value);
   }
   catch Error::Simple with {
   my $err = shift;
   if ($err-text() =~ m/ORA-172/) {
   # handle the error here
   } else {
   # let this error propagate
   $err-throw();
   }
   }; # -- don't forget!


- Perrin




Re: Propogating Errors / E-Toys

2002-06-30 Thread F . Xavier Noria

On Sun, 30 Jun 2002 12:58:08 -0400
Perrin Harkins [EMAIL PROTECTED] wrote:

: Well, naturally the answer is it depends.  Most database errors can't 
: be gracefully recovered from, so we would let them propagate up.  If it 
: was possible for a database error to be caused by user input (say, a 
: duplicate login name) that would need to be caught and handled.  It 
: would also be caught if any special cleanup of non-database resources 
: was needed.

Excellent message, thank you for sharing those experiences once again!

I remember the article has a comment regarding a gotcha of the Error
module that causes memory leaks, but you didn't go into details there. 
I took note of that and am using eval instead of the try/catch syntax
since I do not understand what the problem is and cannot program
avoiding it for sure... I would appreciate very much if you could give
further details (maybe a pointer somewhere) on what origines the leak
and which was your style writing try/catch blocks once aware of the
problem.

Thanks, and best regards from template Barcelona,

-- fxn



Re: Propogating Errors / E-Toys

2002-06-30 Thread Perrin Harkins

F. Xavier Noria wrote:
 I remember the article has a comment regarding a gotcha of the Error
 module that causes memory leaks, but you didn't go into details there.

We've actually discussed this on the list.  It has to do with closures. 
  Matt gave a presentation about exception handling which covers it and 
shows a workaround.  You can see it here:

http://axkit.org/docs/presentations/tpc2001/

- Perrin