The Artima Developer Community
Sponsored Link

Weblogs Forum
How Do You Structure Flow in the Presence of Potential Errors?

18 replies on 2 pages. Most recent reply: Aug 23, 2007 7:09 AM by Frank Silbermann

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 18 replies on 2 pages [ « | 1 2 ]
Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: How Do You Structure Flow in the Presence of Potential Errors? Posted: Aug 1, 2007 9:53 AM
Reply to this message Reply
Advertisement
> I prefer the multiple return/throw statements in C,
> checking for errors before anything is executed. It makes
> the code cleaner and safer in many times.
>
When I wrote this blog last week I was surprised that option 3 came out like a pipe, even though it has no early returns. I think the pipe shape is better than the angle bracket. It is easier to read. But since I can do it without early returns, I'd prefer doing it that way. I didn't get enough responses here to really judge what people in general actually prefer, but many of the responses that came back preferred pipe over angle bracket shape.

I'm curious if those of you who said you like the return statement were to chose between option 1 and option 3, would you choose 1 over 3? If so, why? Because I would lean towards 3.

Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Re: How Do You Structure Flow in the Presence of Potential Errors? Posted: Aug 1, 2007 9:59 AM
Reply to this message Reply
Hi Robert,

> Early on in the history of java, it was understood that
> exceptions should be thrown when a condition occurred
> which the code could not negotiate. That exceptions
> should not be used for flow control.
>
Well technically that's what was going on in this example. The getSignedInUser method doesn't know how to handle the error condition locally, so it throws an exception. But the trouble here is that the intent of factoring functionality out into that getSignedInUser method in the first place was so the programmer could use exceptions for that error particular condition in the handler method. In Java that doesn't feel like a good use of exceptions to me.

> Early on in the history of languages, it was understood
> that functions should have one exit point/return. This
> was not for so much for machine efficiency, but logical
> consistency.
>
I'm not sure this was ever the consensus. I heard people have strong opinions in either direction. The people who liked having many explicit returns tended to do so because they felt it made the code more readable. One reason I heard against it was that it was easier to put a breakpoint right at the return of a method, if there's just one return point. I usually have tried to have just one return, but now and then would stray if it was awkward to do so. Now that I'm starting to use Scala, it has made me want to make each method an expression, whose result is automatically returned. So there's no return statement anywhere in the method. I suspect this will push me into factoring larger methods into multiple smaller ones more than I did in the past, and I suspect that will make my code better.

Rhys Goldstein

Posts: 2
Nickname: rhys
Registered: Jul, 2007

Re: How Do You Structure Flow in the Presence of Potential Errors? Posted: Aug 1, 2007 4:04 PM
Reply to this message Reply
> I'm curious if those of you who said you like
> the return statement were to chose between
> option 1 and option 3, would you choose 1
> over 3? If so, why? Because I would lean
> towards 3.

The problem with 3 is that a single if-else structure does not accomodate a situation like the following:

if (!file.exists()) {
print("Error: file does not exist");
return;
}
text = file.read(); // "in-between" statement
if (text == null) {
print("Error: failed to read file");
return;
}
lines = text.split(); // "in-between" statement
if (lines.size() == 0) {
print("Error: no header found");
return;
}
return parser.parse(lines);

The difference between this example and the original is the so-called "in-between" statements. If you try, I'm sure you'll find that forcing this example into an option 3 structure will result in a big mess. In practice, I find these "in-between" statements very common, so I would not adopt option 3 as a policy for code with potential errors.

Option 1 is a different story. It accomodates the above, and just about any related problem you can come up with. But I also prefer the pipe over the angle bracket shape, so I don't actually like option 1. And of course option 2 has the returns (which many dislike like for various reasons) and option 4 has the exceptions (which don't feel appropriate in all situations).

This problem has interested me for many years, since most of the ugly code I've read/written seems to fall into the "potential error" category. My advice would be to use option 1, but aggressively flatten out the "angle" by introducing booleans and extracting inner structures into smaller methods.

Frank Silbermann

Posts: 40
Nickname: fsilber
Registered: Mar, 2006

Re: How Do You Structure Flow in the Presence of Potential Errors? Posted: Aug 23, 2007 7:09 AM
Reply to this message Reply
The first approach -- big right angle bracket -- is bad because it is difficult for the reader to match up conditions with responses without a ruler.

The second approach (test for error, handle it and return or continue) is easiest to read and understand despite the multiple exits. That would be my first choice.

The third approach (if error then handle it, else do the rest) is semantically the same as the previous approach; it merely adds syntactic clutter. It's only advantage is that if you later have some logic you must append to every single case, you have a place to put it. But YAGNI. This would be my second choice.

The fourth approach (try/catch) is inappropriate use of the language, as others have pointed out. The business logic requires first checking for user error and handling it if necessary. Using exceptions in this case obscures this logic.

How do I decide when, if ever, to use the exception mechanism? I want the text of the code to highlight the _business_ logic; I consider errors caused by fallible users to be part of that business logic which I want highlighted. Errors caused by faulty computer hardware (e.g. databases being down), in contrast, are not part of the _business_ logic and therefore _should_ be buried in a catch block.

If you are concerned that large blocks of error-handling code unduly delay presentation of usual non-error case, then export your error-handling code into their own methods which you call from the main routine.

Flat View: This topic has 18 replies on 2 pages [ « | 1  2 ]
Topic: How Do You Structure Flow in the Presence of Potential Errors? Previous Topic   Next Topic Topic: Last Week's Flex-AIR Jam

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use