Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^6: Style guide for error messages?

by tilly (Archbishop)
on Sep 26, 2005 at 06:56 UTC ( #495019=note: print w/ replies, xml ) Need Help??


in reply to Re^5: Style guide for error messages?
in thread Style guide for error messages?

I'll respond selectively.

I apologize, you pretty much said all of TheDamian's arguments for exception objects are arguments for how to better use them for complex flow of control. I still think that statement is overly generalized and too prescriptive of intention, but perhaps TheDamian does argue for complex exceptional flow control...

By my reading of PBP, the cited benefits of objects over strings have to do with how easy it is to postprocess exceptions in code. His rules on the topic have to do with the advantages for handlers that are trapping exceptions, the best ways to write those handlers and the best way to structure exception class hierarchies. Those are all appropriate to how to use exceptions for complex flow of control. Oh, he also suggests that exceptions should be thrown on all failures, including recoverable ones, which should then be trapped. (The latter choice affects the other choices he makes. Many of his best practices hang together like this - which is why it is a bad idea to pick and choose individual suggestions without a good understanding of why they are made.)

My understanding of those rules and what he wrote is indeed as a series of arguments for how to better use them for complex flow of control. Specifically for flow of control where you are throwing exceptions, catching them in handlers, and the handlers are then making complex decisions on what to do with the exceptions.

When you know the code that is going to handle, or not handle, your exceptions you are not in the situation in which exceptions shine. Exceptions are all about passing control to unknown code.

Yes, that is what they do. That is not what they're for though.

The point of exceptions is to provide a standard way to handle exceptional events without having to litter your code with gotos or checks of returns. Those are the common alternatives in languages without exceptions. Exceptions are better than checking return because it is less error prone. They are better than goto because they lend themselves to clear mental models of what will happen in a particularly important set of circumstances. My preference is to settle on a style that makes that clear mental model as clear and simple as possible.

The problem with string exceptions in Perl is that they are tedious and error prone to identify. Strings must be controlled by convention, Perl can help in this control if typed exceptions are used. Strings are brittle and unhelpful when you need to present your user with info that varies with some context far removed from the error. They just don't scale well. It only takes the need to discriminate a single exception from the many to start feeling this problem.

Let's compare problems. If you use object based exceptions, one problem is that typos will mean that at the point where you're hoping to capture that critical piece of information about an error you'll instead find out that, due to a typo, you lost your information. That seems to me to be a tragedy. You complain about how hard it is to identify strings. By contrast I want a unique enough error message that I can find where it is generated by using grep. Furthermore I'd like strings to be descriptive enough that they document what went wrong. You complain about how to present the information in the exception to users. I'd prefer to be uninformative to users, but detailed to developers. YMMV but I've not had problems with the scalability of exceptions in projects with 100K lines of code. And if it comes to wanting to discriminate one exception, my first question is why you want to do that (sample good reason that I've needd, for an alarm timeout), and my second approach is that it is trivial to include a unique string in the exception. (The first approach that comes to mind is to write a brief explanation in the error, then grep for that explanation. But one could also include a random string.)

You and I could probably get by with printing a message and exiting instead of dieing. This would also make explicit that handling was not intended...

You could, I could not.

I want my file and line number captured. This is far more important to me than adhering to someone else's notion of good style.

(Code snipped.)

I hope you didn't think this code sample was going to change my mind?

Looking at it, what I see is a bunch of code to do the same thing that calling confess does, but less reliably. Oh, it also starts the stack from an internal function call for no real reason. You're being encouraged to separate messages from the place where they are generated, making you less likely to produce a useful message (you know, one with $!, arguments, a statement of what you were trying to do..). The default message is uninformative And your fail() function won't accept an argument, so you're guaranteed to get the default message. Plus, as I mentioned before, if you have a bunch of these, a typo on a class name when you call the exception can leave you with a hidden landmine - you think you're going to get a useful message when you're not! (Of course I could also have a typo typing confess(), but since that is just one word and my fingers are very used to typing it, I'm unlikely to mess that up. I'm far more likely to mess up class names.)

To recap, here is a summary of my position.

For the simple case, objects are worse than strings. If you want to be more complex, then objects are an obvious win. I'd prefer to KISS, and would like to discourage complexity. (Admittedly, there are applications where that complexity is needed, but I'm not dealing with any.)


Comment on Re^6: Style guide for error messages?
Re^7: Style guide for error messages?
by rir (Vicar) on Sep 26, 2005 at 21:39 UTC
    You mentioned gotos and returns. On this list should be the closer cousin: semaphore flags. Flags are worse than exceptions because they are advisory.

    I want my file and line number captured.

    That goes into the message.

    I was not complaining nor was I trying to change your mind (or practices); even brilliant men can disagree.

    I'd prefer to be uninformative to users, but detailed to developers.

    With objects one can inform both appropriately.

    if it comes to wanting to discriminate one exception, my first question is why you want to do that

    An example: A fair sized body of code, being 7 or more calls deep, explores the environment of the program. The scope of the environment is expanded and now failure to access a few resources is no longer reason to exit, instead by expressing the problem at the new top level, a separate tree of code is able to substitute some of the new resources instead. So now we want to discriminate a few exceptions from the many. Capturing some data to present to the user may also be appropriate.

    That your fingers are trained to type confess is a valid and compelling reason to practice as you do, but it gave me a laugh. I thought of some programmer trying to use that as a justification to his boss--what made that image really funny is that such idiocynratic issues can have a serious impact on productivity.

    For the simple case, objects are worse than strings. If ... more complex, then objects are an obvious win.

    I agree with your opinion as you summarize it.

    Be well,
    rir

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://495019]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (7)
As of 2014-08-02 04:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Who would be the most fun to work for?















    Results (54 votes), past polls