Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Exception Classes Advice on Subclasses

by jffry (Hermit)
on Dec 21, 2005 at 03:44 UTC ( #518228=perlquestion: print w/replies, xml ) Need Help??

jffry has asked for the wisdom of the Perl Monks concerning the following question:

I'm using Exception::Class to define my exceptions classes, but I just stumbled into a design question. Should create lots of exception subclasses like this?
MyExceptions::SomeThingy MyExceptions::SomeThingy::SomeSpecificError MyExceptions::SomeThingy::AnotherProblem MyExceptions::SomeThingy::DontDoThat
But if the subclasses SomeSpecificError, AnotherProblem, DontDoThat aren't different, then why have them? I was thinking of replacing those subclasses with fields under SomeThingy. Like this:
MyException::SomeThingy' => { isa => 'MyException', description => 'Bad things happen here.', fields => [ 'descriptor', 'value' ], };
And then I throw them:
MyException::SomeThingy->throw( 'error' => 'You did something I didnt like.', 'descriptor' => 'DontDoThat', 'value' => $bad_variable, );
Hmmm. So I guess my question is, if all those subclasses do the same thing, am I getting anything out of creating them all? Other than the name of the exception itself tells me something about the error? If that is all I am gaining, then doesn't using fields make more sense? I'm new to OO, and new to using Perl as anything other than a glorified awk. Thanks.

UPDATE: This page covers what I was asking, too, in the paragraph titled "Write Sensible Throws Clauses".

Replies are listed 'Best First'.
Re: Exception Classes Advice on Subclasses
by adrianh (Chancellor) on Dec 21, 2005 at 10:16 UTC
    Hmmm. So I guess my question is, if all those subclasses do the same thing, am I getting anything out of creating them all?

    You get a more convenient syntax for catching particular exceptions. For example:

    if ( my $e = MyException->caught ) { ... } elsif ($@) { die $@; }

    much easier than delving into fields to figure out what kind of exception has been thrown.

    You also get a simple way to represent a hierarchy of exception types. If you have a general ValidationError exception class, with a DateValidation, NameValidation, etc. subclasses then you could capture all of the subclasses with a single ValidationError->caught.

Re: Exception Classes Advice on Subclasses
by tirwhan (Abbot) on Dec 21, 2005 at 10:28 UTC

    Caveat: I've never used Exception::Class in anger, so take my comment with a grain of salt.

    I think the main point of using different subclasses is that you can check for the subclass directly when 'catch'ing the exception, and handle it appropriately to the type of error encountered. For example

    use Exception::Class ( 'X::FatalIOError' => { # fields etc. }, 'X::TimeOut' => { } ); eval { somecode() }; if ( X::FatalIOError->caught()) { # do something and die } elsif (X::TimeOut->caught() ) { # wait and retry } elsif (Exception::Class->caught() ) { # got an exception we weren't expecting # die horribly or something }

    Sure, you could set up something similar with using a single MyException subclass and testing the contents, but it seems a lot cleaner this way.

    Update: Heh, adrianh answered the question before my post made it. Oh well, take my post as a more extended example :-)

    Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
Re: Exception Classes Advice on Subclasses
by venk (Acolyte) on Dec 21, 2005 at 13:39 UTC
    I suggest using subclasses rather than trying to differentiate your exceptions through 'fields'.
    if ( my $e = X::Class::SubClass1->caught ) { # handle } elsif ( my $e = X::Class::SubClass2->caught ) { # handle }
    In each block, the above code directly describes the type of error that it handles --- I think using 'fields' requires the reader to work a little harder to understand what is going on. That said, I recommend not getting carried away with defining complex exception hierarchies. Start with a simple X::Class->caught and subclass only as required by your application.
Re: Exception Classes Advice on Subclasses
by halley (Prior) on Dec 21, 2005 at 17:25 UTC
    In Java and C++, exceptions are typically instances of some class, and are "thrown" by bad code and caught in surrounding "try/catch" syntax.

    While some people have built these elaborate synonymous structures using Perl packages, I have found very little advantage in them over using Perl's built-in exception mechanism.

    In Perl, exceptions are a scalar value, stored in the special variable $@. These exceptions are "thrown" by bad code using the keyword die and caught in surrounding code by eval { } syntax.

    The advantages of classes appears to be when there are so many possible causes of failure that you need to send back uber-complex reporting structures to attempt to explain it. If you don't need all this complexity (and you should always avoid undue complexity), just use die/eval.

    Write Perl in Perl idioms using Perl's mechanisms. Otherwise you're just coding in Java or C++, but sprinkled with funny sigils.

    [ e d @ h a l l e y . c c ]

      Write Perl in Perl idioms using Perl's mechanisms.

      Yes. Yes. YES!

      That should be added to the Monk's quips and displayed on every page of this site.

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Exception Classes Advice on Subclasses
by blazar (Canon) on Dec 21, 2005 at 11:13 UTC

    I'm not familiar with Exception::Class, but AFAICT it seems to me that if you use fields then you will have to manage them at throw() time, whereas if you use subclasses, which may seem a slightly less compact approach but really still amounts to code-reusing, you will have an immediate syntax to just throw() an exception as needed.

    Basically, as it often happens, it is mainly a matter of personal taste/preference. You could even adopt a mixed approach. Personally I guess I would go for subclasses.

Re: Exception Classes Advice on Subclasses
by perrin (Chancellor) on Dec 21, 2005 at 17:38 UTC
    Others have pointed out why you should have different classes instead of parameters. I'd add that there is no point in having exception classes if you don't intend to catch them and continue. If all you want is a nice error message, then just croak() and be done with it. Exception::Class is useful when you have conditions that could be caught and recovered.
Re: Exception Classes Advice on Subclasses
by jesuashok (Curate) on Dec 21, 2005 at 05:29 UTC

    From your posting I am able to understand that If Three

    classes are going to have the same functionality then Obviously we can make it as single(one). That is what the flexibility of oops

    But I am not much clear about your posting still.

    thorough Perl OO we can do many in things in flexible manner.

    Please refer the manual of Perl which is Related to perl OO.

    "Keep pouring your ideas"
      I'm replying to the first response, but really this is to all who responded.


      I hope it isn't inappropriate to post replies of thanks at Perl Monks, I see jokes being posted, so I assume that thanks aren't forbidden. Thanks even (especially?) to those who wrote, in so many polite words, "Stop using Perl OO, you fool!" You made me spend a few hours justifying my use of OO to myself (yet again).

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://518228]
Approved by Tanktalus
Front-paged by Tanktalus
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2022-08-19 04:27 GMT
Find Nodes?
    Voting Booth?

    No recent polls found