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

RFC: A better name for an exception handling module?

by ELISHEVA (Prior)
on Dec 22, 2010 at 16:07 UTC ( [id://878578]=perlquestion: print w/replies, xml ) Need Help??

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

I am looking for recommendations for a better name for an exception handling module I wrote about a month ago.

The current name Exception::Lite reflects its original motivation, but not its purpose at all. Even though it is still light weight (really! it doesn't take much to create all the features I list below), it has a lot of features that aren't at all advertised by its name.

I developed the module because the existing OOP-ish exception handling modules on CPAN were heavy on things I didn't really need (syntactic sugar, per-property accessor methods) and didn't have the features I really, really did need to construct messages and debug code efficiently. The closest I came was Exception::Base which is about the only module on CPAN that captures the thread id, but it doesn't provide the property/message integration or debugging information that I crave. Features like:

  • Closely integrated messages and exceptions properties. I wanted to be able to assign values to properties and have the message autogenerated based on those property values. The code for it is really quite simple, but for some reason, none of the modules consider this terribly important. Not only does this save time and typing, it also makes it much easier to retrofit the code with localized messages: just stick the property values into a new language specific format string.

  • The thread id at the time the message is generated.

  • Chained exceptions. Sometimes what a low level module considers important about an exception is not what a higher level module considers important. When that happens I want to create a new exception with a more relevant error message that "remembers" the exception that inspired it so if need be, I could see the entire history from origin to destination.

  • The ability to see propagation history (where an exception is rethrown) and not just the chain of calls that were made to get to the original place the exception was generated.

  • A stack trace that tells me what subroutine the problematic code of line is located in rather than what subroutine was called on the problematic line. If I'm scanning a chain of calls, I want to see the context where the problem occured not just a pinhole view of the actual line where the problem occured.

  • A stack trace that won't lie to me about the parameters that are being passed to subroutines. I know it is impossible to recreate the actual values in the parameter list because the parameter list for any sub is just @_ and that can be modified when a programmer uses shift to process command line arguments. The most the DB module can give me is the way @_ looked at the time the next frame in the stack was set up. Still most stack traces are formatted as if they are showing the actual parameters passed to the sub rather than what was left of them by the time the next stack frame was set up.

    If the programmer used my ($arg1, $arg2,...) = @_ and never used shift or anything else that modifies @_ it will just happen to be the values passed to that subroutine. But often subroutine arguments are processed with shift and by the time the next subroutine is called, @_ is stuffed with a bunch of leading undef's. It no longer looks like it did when the sub was originally called. Why not just tell me it is the value of @_ at the time the next frame was created so I don't think I passed a heap of undef's to my subroutine? Better yet, provide me some sort of visual hint that those undefs might be bogus so I don't have to do that extra thinking step each time I see them. I want to focus on the code, not on remembering the quirks of Perl stack tracing.

  • An uncluttered stack trace where I can easily control the amount of detail and won't have error messages truncated (a problem with Carp::croak). Sometimes being able to see what subroutine was calling what other subroutine will tell me everything I need to locate the bug. I don't always want to see chained exceptions, the propagation sequence or even what's left of @_ at the time the next frame in the stack was generated. In fact, that is true most of the time. All I need is a simple list of what called what on which line of which file.

  • Can shed its OOPishness and still be useful when someone tries to handle it and doesn't know or care what sort of exception it is. I want it to be used as a string in string context. I want it to be well behaved in equalities and compare reference addresses. It needs to be thrown and rethrown using normal Perl symantics, e.g. die $myerr to throw and die without parameters to rethrow.

On my less important but still nice list:

  • A way of declaring exceptions that doesn't make me bunch them all up in an ugly hash at the top of my script. Call me fussy but I find the way that Exception::Class wants me to declare exceptions ugly and unwieldy.
  • No fixed base class with obscure subclassing semantics. I want to control the heirararchy of my exceptions.

OK. I'm done. It isn't much really? Is it?

Fortunately not. The actual exception classes are between 30 and 45 LOC even with all the property/message integration. The code to set up and control the stack trace, chained exceptions, and propagation history amount to another 150 lines. Perl has some marvelously efficient tools for exception handling in its core. They just need to be assembled. caller, DB::args, sprintf, overload and PROPAGATE are my friends.

Being light weight is an advantage, but not its real value, at least not to me. Thus I consider the current name not very useful, especially if I ever get the courage to submit it to CPAN. (The long term responsibility of maintainership worries me which is why I haven't released any modules to date.)

Some of the names I've considered:

  • Exception::Threaded - since there is already one other module that tracks tid, this isn't really a distinguishing feature, but I would like a way for someone to know that this module does support it.
  • Exception::MessageAndPropertiesIntegrated - this is, of course, way too long. The CPAN recommendation is that each segment try to be 11 characters or less with the initial 8 being unique. See http://www.cpan.org/modules/00modlist.long.html
  • Exception::Informative - of course that is my personal opinion, but I just don't think that is a very good name. A useful name should be something other than "what Beth thinks of her module".
  • Exception::PrettyStackTrace - a little more description, but also too long and still my opinion. Additionally, the control over the stack trace is only part of its value.

As you can see I am naming impaired and would welcome help from my fellow monks. And if someone helps me come up with a decent name and if someone other than I thinks that these features would be helpful, I'll consider biting the bullet of long term responsibility (any thoughts on that issue would be welcome as well, by the way), and post this module to CPAN.

Update: added code, pod excerpts, and test suite in reply Re^2: RFC: A better name for an exception handling module? as per TGI's request.

Replies are listed 'Best First'.
Re: RFC: A better name for an exception handling module?
by jethro (Monsignor) on Dec 22, 2010 at 17:27 UTC

    You should keep in mind that a name *::Lite would look very appealing to many programmers who already have to include lots of module monsters into their code.

    If your module just seems to differ in the details from the other modules you might as well just take a nondescriptive name. Rose::DB or Moose got used for their merits and not for a catchy name after all.

    But the overall impression I get from your module description is that its output is just more informative than all the other Exception modules, so how about

    Exception::Descriptive

    Exception::Informative

    Exception::Clear

    Exception::More

    And I, for one, welcome our new exception overlord ;-)

      Thanks for your feedback. I like the name Exception::Clear and your point about "::Lite" is well taken.

      I am concerned by the perception that he overall impression I get from your module description is that its output is just more informative than all the other Exception modules

      This points to a failure on my part to clearly describe the exception class and what it adds. Better management of the actual creation of exceptions was also a goal. In fact it was the original motivation. I only added the improved debugging output later on as I put the exception class into production. In all of the other modules I could find, you can define properties and you can define a message, but if there is any connection between the two, you have to set it up outside the exception, or else create a subclass of the module.

      In Exception::Class and pretty much all of the other OOPish CPAN exception modules you have to do something like this:

      #... at the start of your code ... # notice how exception definition and message format # string constant are in two different places and need # to be manually coordinated by the programmer. use Exception::Class { 'Exception::Copy::Mine' { fields => [qw(from to)]; } # ... lots of other exceptions here ... } my $MSG_COPY='Could not copy A.txt to B.txt"; ... later on when you throw the exception ... # notice the repetition in the use of exception # properties; the repetition is error prone and adds # unnecessary extra typing my $sMsg = sprintf($MSG_COPY, 'A.txt', 'B.txt'); Exception::Copy::Mine->throw(error => $sMsg , from => 'A.txt' , to => 'B.txt');

      As far as I can see, none of the other modules allow you do do something succinct and easy to maintain like this:

      # the declaration puts the message format string and the # class declaration together for the programmer, thus # resulting in less maintenence work declareExceptionClass("Exception::Mine::Copy" , "Could not copy %s to %s", [ qw(from, to) ]); .... some where else in your code ... # there is no need to explicitly call sprintf or # repetitively type variable names, nor even remember # the order of parameters in the format string or check # for undefined values. Both of these will produce # the same error message: # "Could not copy A.txt to B.txt" die "Exception::Mine:Copy"->new(from =>'A.txt', to=>'B.txt'); die "Exception::Mine:Copy"->new(to =>'B.txt', from=>'A.txt'); # and this will politely fill in 'undef' for the # property you leave out: # "Could not copy A.txt to <undef>" die "Exception::Mine::Copy"->new(from=>'A.txt');

      @jethro: I agree with you comment about *::Lite.

      <rant>
      However, please don't encourage more meaningless names. Meaningful names is one more plus in favour of CPAN, and lack of them is one of my pet peeves about python's library. Moose is a great set of modules and I use them, but I don't like the name; I am willing to concede that all the good names I can think of are already taken. There's a really nice networking framework in python called: Twisted. I think that's twisted and not helpful. I can find useful modules in CPAN by browsing categories.
      </rant>

        I cannot agree more. "Cool" names are kinda OK for the big things like frameworks, but definitely not single purpose modules. Hpricot anyone? Yet another reason I hated Ruby.

        Jenda
        Enoch was right!
        Enjoy the last years of Rome.

Re: RFC: A better name for an exception handling module?
by ELISHEVA (Prior) on Dec 22, 2010 at 16:46 UTC

    Here's a few samples of the different kinds of error messages generated, based on various control variables.

Re: RFC: A better name for an exception handling module?
by Anonymous Monk on Dec 22, 2010 at 18:26 UTC
    Throw::Fit :)

      Tee hee hee.... this works on soooo many levels. :-)

Re: RFC: A better name for an exception handling module?
by stvn (Monsignor) on Dec 22, 2010 at 20:51 UTC

    Have you taken a look at Throwable? It is an excellent base exception role and I have found it very easy to work with and extend for my needs. It maybe fails your lightweight requirement since it uses Moose, but at the very least it might be a source of inspiration/ideas.

    As for naming, I recommend something animal themed ;)

    -stvn
Re: RFC: A better name for an exception handling module?
by RedElk (Hermit) on Dec 22, 2010 at 17:11 UTC

    Tho probably not any more descriptive, from your own words Exception::Crave comes to mind. FWIW...

  • Exception::CraveLite
  • Exception::CraveMore
  • Exception::CraveInfor
Re: RFC: A better name for an exception handling module?
by Anonymous Monk on Dec 22, 2010 at 19:01 UTC
    • Carp::Exception (see Carp::)
    • Die::Well (see Die::Alive)
    • Devel::Kplah (perl -d:Kplah)
    • Devel::K::plah (perl -d:K'plah)
    • Devel::HEGHHJAHJ - die well (perl -d:HEGHHJAHJ)
    • Devel::HeghQaQ - die well (perl -d:HeghQaQ)
    • Exception::DollarAt (see Devel::DollarAt)
    • Exception::LogIt
    • Devel::DollarAtT - the T is for thread id
    • Devel::Exception (see Devel::CallStack, Devel::Eval )
    • Devel::lException (perl -d:lException ...)
Re: RFC: A better name for an exception handling module?
by TGI (Parson) on Dec 23, 2010 at 05:38 UTC

    Do you have anything on github or somewhere simlar so that we could see/play with the code?

    One can't really name a thing one hasn't seen...

    Exceptions are an area where Perl needs a Try::Tiny or a Moose to come along and make things good.


    TGI says moo

      Code posted below.

      And some excerpts from the pod with a synopsis and a discussion of subclassing and localization.

      And, of course, a test suite, because what module doesn't have one?

      One interesting detail: it takes about 3x as many lines of code to generate the exception as is in the actual exception itself.

      Hmmm.

      Update: Just noticed a "print STDERR" that I meant to comment out and didn't - so now it are commented out. The line displays the code for the generated class. If you want to inspect the generated class, you can re-uncomment it.

      .
Re: RFC: A better name for an exception handling module?
by tilly (Archbishop) on Dec 28, 2010 at 06:23 UTC
    Exception::Context?

      Thanks! I really like this name. It does succinctly capture the main benefits:

      • Bug context: The stack trace's main feature is that it more clearly shows the context of the problem
      • Programmer context: The integration of messages and properties means that exception creation takes better advantage of information available to the programmer. The programmer does not need to restate things in more than one place.
      • End user/development context: The ability to retrofit/add locality support with a minimum of advanced planning means you can better fit the exceptions to changing development contexts and end user needs

      Are there downsides to this name? Right now, it is coming down to a tie between Tilly's suggestion and the original name Exception::Lite due to Jethro's observations about "Lite" being an important selling point.

      The job of a good name isn't to be "cool" but to attract the people who will eventually want the package enough to download it. In theory you can sell something with any name, but when the name and the product are mismatched it is a lot more work. What is the difference between a person who would click through to Exception::Lite vs. Exception::Context? Which name would attract the people who would end up downloading it?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-03-29 07:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found