Beefy Boxes and Bandwidth Generously Provided by pair Networks Bob
Don't ask to ask, just ask
 
PerlMonks  

Re^3: Error handling - how much/where/how?

by mstone (Deacon)
on Jun 15, 2005 at 20:34 UTC ( #467051=note: print w/ replies, xml ) Need Help??


in reply to Re^2: Error handling - how much/where/how?
in thread Error handling - how much/where/how?

You're really gonna hate any() values (and traits) when Perl6 comes around. ;-)

If you want more information about what went wrong, put more values into the return set. You know.. like NaN, positive and negative infinity, "Number outside representation range" and that sort of thing. You could also add utility values like positive and negative zero, or 'Infinitesimal' which make certain calculations easier.

If you want even more information, you can choose which of:

  • NaN_divide_by_zero
  • +/-Infinity_divide_by_zero
  • or just plain Divide_by_zero

fits your purposes best.

You're also missing the point that value should always contain something consumable by the main-line client code. The goal is "usable but identifiably bogus" rather than "broken but correct."

If I were writing a division operator, for instance, I'd probably have division by zero return:

{ 'value'=>1, 'is-valid'=>0, 'error'=>'Divide_by_zero' }

The one in value is consumable by any other mathematical operation, even though it's totally bogus as an accurate result of the calculation. The boolean in is-valid tells you it's bogus, and the detail code in error tells you why. (Yeah, error is new. I added more information. We can do that)

If I really wanted to get spiffy, I'd add still more information:

{ ... 'trace'=>"($a/$b)" }

then write all my operators so they return progressively more complicated trace strings whenever they get invalid arguments. That way, I could see at a glance where the error occured, rather than having to fire up a debugger and step through the code until it bombs out again.

IMO, the presence of exceptions is a code smell. It says that you'd rather use the quantum superposition of two (or more) possible code sequences in a "try it, then backtrack and see what went wrong" fashion rather than figuring out how to make the code work in the first place. And it's almost always a sign that the programmer is trying to use a data representation that's too primitive to handle all the results that are actually possible.

So.. you can write Schrodinger-code to compensate for the bad decisions you made about data representation, or you can choose a data representation that actually does what it's supposed to, and handle the job correctly.


Comment on Re^3: Error handling - how much/where/how?
Select or Download Code
Re^4: Error handling - how much/where/how?
by Jenda (Abbot) on Jun 16, 2005 at 00:43 UTC

    No, I'm not gonna hate any or traits. You are missing the point. I just won't put up with a module that forces me to jump throught the hoops to get at the value. That was the main point, not the fact that the hash did not contain the error details.

    If the operation failed there's no point in it returning "something consumable by the main-line client code". The main-line code should NOT consume the value at all! Which, using your style means that I have to test everywhere and then on a hundred more places whether the thing I received is indeed a value or an error. Which means that 1) the code will be much longer and 2) I will surely forget to test it on some places.

    Why is your division operator returning 1? How is 1 "usable but identifiably bogus"? 1 is a totaly reasonable result of division, even if it's bogus in some cases (using your division operator) there's nothing identifiable about it.

    And for your division operator to be at least barely useable you'd have to define it not (just) on numbers, but also on your "maybevalues". That is on those {value =>..., 'is-valid'=>...,...} structures? And you'd likewise need to define all the other mathematical operators. So that the user may at least (mind you I'm not asking for anything fancy) write code like $mayberesult = 1+ $x/$y (assuming the / is that your division operator. Of course that code would not be complete, after that the user would have to add something like

    if ($maybevalue->{'is-valid'}) { ... } else { report the problem somehow, maybe return another maybevalue from the +current procedure }
    You like this code? Well I don't.And I don't believe noone ever looks at the $maybevalue->{value} without consulting $maybevalue->{'is-valid'} first.

    Next thing. What's the result of {value => 1, 'is-valid'=>0,error=>'Division by zero'} / {value => 1, 'is-valid'=>0,error=>'Number outside representation range'}? Do you choose just one of the errors? Do you combine them? How? And if you keep the trace, how do you combine that? And how's the "main-line code" supposed to make any use of that then?

    Exceptions let me handle the problems at the level I need, without caring at the deeper levels. Which may mean that I won't know where exactly in some computation does the div-by-zero originate from ... but most likely I don't care. I just need to handle the problem without blowing he code out of proportions with tons of maybevalue handlings. We have a job to do and it's not to write a program you can prove to be correct, but rather to write a program that does what it's supposed to and to do so in a reasonable time.

    Jenda
    XML sucks. Badly. SOAP on the other hand is the most powerfull vacuum pump ever invented.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (7)
As of 2014-04-18 11:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (466 votes), past polls