Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

When throw exceptions?

by Anonymous Monk
on Jul 10, 2012 at 10:54 UTC ( #980851=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

While writting OOP code, should I always throw exceptions or am I allowed to use croaks in certain situations?

Replies are listed 'Best First'.
Re: When throw exceptions?
by sundialsvc4 (Abbot) on Jul 10, 2012 at 12:05 UTC

    All that I could really offer is “what works for me.”   In pretty much all of my recent code, you’ll find this near the top:

    use Try::Tiny; use Exception::Class; use Exception::Caught; use except::classes; use Data::Dumper;

    If you search for these at, you will see how each one of these work.

    I write code so that it either succeeds or it dies, and when it dies I prefer that it throw an exception-object so that it can carry a “payload” about exactly what happened, without me having to try to deduce it from a text-string.   I also find it useful that, with the mechanisms cited above, I can get the traceback of called routines without at that moment spewing it out to STDERR.   This allows me to, for example, get a truly useful diagnostic message in the Apache logs without, so to speak, throwing up on the web user’s screen.

    Specifically:   I set up a hierarchy of exception-classes in one application-wide shared module.   The outer-level loop of the program contains a “catch-all” handler which will intercept any exception that no one else has caught.   Each significant block of code contains a surrounding exception-handling block, and it “re-throws” any hot potato that it does not itself know how to handle.   My code is aggressively and constantly checking itself for errors, testing every assumption with an assertion, with the result that while it will throw a slew of errors during testing, the pattern is that “suddenly, and pretty much forevermore, it stops.”   Each time I am shooting down another bug, I am always able to know with a fairly high degree of precision where to find it.   (Which is, as the credit-card commercials say, “Priceless.”)

    Part of the perldoc which I dutifully write for every package/object is a discussion of the exception classes that this object may (directly) throw, and under what conditions it will do so.   The exception is, as it were, “a possible output,” and the object’s contract with its caller is that, if it successfully returns control back to you, at all, then you can rely that it [thought in good faith that it] successfully did what it was told and returned a reliable answer.   The package which contains all of the exception classes, in turn, dutifully contains a description of each one.

      This is the best practice IMO. Very well said. I'm still laughing about "Throwing up".

      I would like to have a look at your exception hierarchy. Is it possible?

      Best regards

Re: When throw exceptions?
by zwon (Abbot) on Jul 10, 2012 at 11:28 UTC
    Croaks are exceptions, use them if you like it. I personally mostly use die and croak, and avoiding Exception::Class style exceptions, as IMO they only bloat the code and make it harder to find problems. But it is matter of taste.
Re: When throw exceptions?
by nemesdani (Friar) on Jul 10, 2012 at 11:08 UTC
    Basically: as you wish. Which serves you better? Do you need the location where your subroutine was called (bad usage), or the location where the s*** hit the fan (probably the subroutine itself is buggy)?

    I'm too lazy to be proud of being impatient.
Re: When throw exceptions?
by talexb (Canon) on Jul 10, 2012 at 15:02 UTC

    I wrote an API about a year ago using Dancer whose methods returned two items, a result object and an application error. If the result object was undef, then the application error would be defined, and that error was passed back up the object hierarchy to be returned to the caller.

    During the code review for this API, I was criticized for not implementing this as a die or croak. It's a matter of taste -- for me, this type of error was application level, and not system level; it's something that could safely be reported back to the caller. IMO, a system level error would be something catastrophic like the database connection being unavailable.

    Really, it's up to you -- make a decision how you're going to design your application, and after that, just be consistent.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      /me nods...

      And I would have been one of those dissenting voices in your review committee.   If you had told me that the returned object was some kind of a status record, I might have asked why you then did not simply return one structure (like a typical JSON response structure) in which both the status and the result were part of a single record/hash.   If it were an error, and (I am not knowledgeable of Dancer) it was not a situation very much like that of a JSON response, I, too, would have advocated the throw-an-exception mechanism because of its ability to circumvent “all those tests.”   (Then I would have listened, attentively, to your counter-argument, and have been fully prepared to reverse my position in your favor.)

      I entirely agree with your closing comment, however:   make a decision, and thereafter be consistent.

Re: When throw exceptions?
by Anonymous Monk on Jul 10, 2012 at 20:06 UTC
    Exceptions are exceptional. Do not catch them. Use error or status numbers instead. Exceptions should never happen during runtime. For a context that must throw an exception, it must be a scenario that requires administrator intervention (a security breach attempt, upstream server timed out, etc) and is not software correctable.

      I disagree, (And I can tell you have not done any coding in Java). Exceptions are exceptional, but they need not be fatal errors. In OO development it makes sense for a method call to return useful results via it's normal return, and to signal problems via thrown exceptions that can be caught by the caller. (or further up the call stack).

      For example, consider the Java exception class Class FileNotFoundException. If you where writing an interactive application, then it would usually make sense to catch this exception, because the likely cause would be something like the user mis-typing a file name. In other words, not a fatal error, but something that can easily be dealt with. It is also a subclass of, which makes sense as in a lot of situations you would want to handle many different types of I/O problems in the same way, so you can catch them all by having a catch statement for the superclass.

      Compare that with using return codes to indicate exceptions. You end up in a situation where -1 is File not found, -2 is permission denied etc. You have to document all the different return codes, and carefully propagate them back through several layers of callers. Your code also becomes much more verbose as you need to check return codes on every API call, and save them to propagate back up, this becomes doubly complicated if you are using a third party API with a different convention on what is meant by each status number. It is far easier, (and more concise) to write clean code that mostly assumes that stuff will work, and does not needlessly repeat exception handling stuff.

      Another great feature of exception handling via throwing and catching them is that the catch can be several calls up the stack from the throw. So you can have a private method that actually does the work several layers down from the public methods of a class and still reliably return errors.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://980851]
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2017-08-19 17:40 GMT
Find Nodes?
    Voting Booth?
    Who is your favorite scientist and why?

    Results (312 votes). Check out past polls.