Exceptions, Exception::Class, and a quick hack

kellan on 2002-01-29T04:15:50

I've just recently returned to the land of complex Perl applications after many years wandering in foreign climes. And while it feels good to be back, I sorely miss some of elements of those exotic cultures. For example, exceptions.

So, surpised, and very happy, was I to find Error.pm, clean of interface, with a nicely developed try/catch syntax.(plus an otherwise keyword, which I forcely ignored)

However it was not to be. Dire were the warnings against Error.pm and its memory leaks.

So I've started playing with Exception::Class. While it does not have the comfortable familiarity of an old friend that Error.pm had, it comes reccomended, and with some of its one pleasures.

But, I'm stuck using the

eval {}; if ($@)
syntax, which is, for all intents and purposes new to me.

And I hit a snag.

See, my code would be merrily executing along, and then throw some nice, explicitly named execption like:

throw RW::Exception::App::BadPassword();
Now I don't feel any need to pass an error message to this throw, the name of the exception makes clear what it does.(its self-documenting ;)

However when I go to catch it, with some code like:

if ($@ and $@->isa('RW::Exception::App::BadPassword') )
the first test fails. And it fails because Exception::Class overloads stringification.

Exception::Class's as_string method returns the error you passed to throw (nada in my case) and possibly the stack trace. (which I didn't have enabled) So when I tested for the existence of an exception, I was testing the truth value of an empty string.

So after 30 frustrating minutes of wondering why my exceptions where disappearing into thin air, I overrode Exception::Class's as_string with my own:

sub as_string {
my $self = shift;
my $str = Exception::Class::Base::as_string( $self );
my $name = ref($self);
return "$name: $str";
}
Now all my exceptions test true. Yeh. 30 minutes to debug, 5 minutes to code, and 20 minutes to write a usePerl journal entry, leaving 5 minutes to grab a cup of coffee, and make a well spent hour.


Error.pm

Matts on 2002-01-29T12:09:04

Error.pm had exactly the same bug. The *real* solution is to overload boolean context:

{
  package Exception::Class;
  use overload 'bool' => sub { 1 };
}

But you probably didn't want to know that right now ;-)

But interestingly I don't see why people can't just use Error.pm's class structure without the try/catch semantics. At least until I get around to writing Error::Filter so that there'll be no more closures.

Re:Error.pm

kellan on 2002-01-29T22:00:58

But you probably didn't want to know that right now ;-)
No! Thats great. I think I'll leave my as_string overload because its useful for debugging purposes, but it was such an ugly kludge I was doubting my senses for returning to perl.

re: Error::Filter, yeah I remember reading about that in your journal months ago, so where is it? Do you think we'll see it before Perl6 comes out and makes all this silly jiggering around obsolete? :)

Btw. is the a reason to use Error.pm over Exception::Class?

Re:Error.pm

Matts on 2002-01-29T22:18:08

re: Error::Filter, yeah I remember reading about that in your journal months ago, so where is it? Do you think we'll see it before Perl6 comes out and makes all this silly jiggering around obsolete? :)

Well I lost what I had in a hard disk crash. I guess if there's enough interest I'll try and put something together for my exceptions talk at TPC (assuming it gets accepted). But don't expect anything too soon - as soon as I know what talks get accepted I'll be in major head-down mode writing talks...

Btw. is the a reason to use Error.pm over Exception::Class?

It's shorter to type? ;-)