Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I like exceptions too. But it is a pain to use exceptions for all failures. Exceptions should be "exceptions" and not indications of a "normal" failure (at least, that is the most accepted practice in the areas I find myself working). The line between the two can be subtle.

Trying to open a file for reading when that file does not exist would not usually throw an exception because that is an expected failure mode. Getting an error when reading from a file (besides "end of file", which is sometimes described as an error) should throw an exception.

Aside: I find it interesting that you pick errors reading from files for your example. A few months back I was writing about best practices when reading files in Perl. I came to the conclusion that checking for non-end-of-file errors (that is, real errors) when reading from a file handle is just not worthwhile. 1) They are difficult to detect. 2) It is hard to imagine situations where such happens. 3) In the rare cases where it does happen, the best reaction is often to treat it like a premature end of file (except that it would be nice to note that the end of input processing was due to an error and what that error was). So I'd love to see the read primitives of Perl issue a warning if they "fail" for reasons other than end-of-file. But I'm not sure that throwing an exception for that case would be the best choice.

So I'd be interested in hearing about the "nasty bugs" that you've run into related to read failures.

So what is an exception and what is a "normal failure"? There are two ends to the spectrum, of course. Perl is close to the "all failures are normal" end, only throwing exceptions for extreme things like compilation failure. Perl 6 sounds like it will be close to the "all failures are exceptions" end.

The problem with the former is that it is way too easy to forget to check for failure and so failures get ignored when they shouldn't. The problem with the latter is that it can be inconvenient to put catch blocks everywhere you should -- though this "problem" probably leads to better programming.

So the case is pretty clear that we should go the route of Perl 6 and have all failures be exceptions. I'll probably agree except that this is Perl 5 and so most failures aren't going to throw exceptions, most Perl 5 programmers aren't used to dealing with exceptions, and Perl puts a big emphasis of programmer convenience. So in Perl 5, I want to drive down the middle of the road on this point.

Which brings us back to: What is an exception and what is a "normal failure"? Take the "trying to open a non-existant file for reading" example. In the general case, it would be inconvenient for Perl 5 to throw an exception for this. In specific cases, you do want to throw an exception for this. The usual idiom for distinguishing the two cases is:

open( FILE, "<" ) or die "Can't read $!\n";
if( ! open( FILE, "<" ) ) { # Deal with the absense of this file }
which begs the question, what should be done with this:
open( FILE, "<" );
In Perl 5, the answer is simply that this code is broken and should be fixed to one of the previous two cases. My answer is that Perl 5 is "broken" and should treat this like the first case automatically.

And that is the point of my design for an error object. It makes it convenient to treat a failure as normal but automatically converts a failure into an exception when it should.

So part of the point of my error object is to make it easy to generate exceptions for failures. So you should like it. The difference between my approach and yours is that my approach allows each caller to decide (or to not even think about it in which case the decision is made for them) what is normal failure and what is an exception. In your approach, the callee makes that decision for everyone and forces them to convert between the two cases when that decision doesn't match their situation.

And the problems with converting are: 1) Converting from exception to handled failure is inconvenient in Perl 5. 2) Converting from normal failure to exception usually requires that the caller construct the error message when the callee usually is in a better position to do that. But the error object forces the callee to construct a useful error message while also allowing the caller to add to it (or ignore it).

                - tye

In reply to Re^3: Best Practices for Exception Handling (no isa) by tye
in thread Best Practices for Exception Handling by Ovid

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2021-10-27 10:53 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (91 votes). Check out past polls.