Friday, December 24, 2010

Handling Failure

Here are two coding styles for handling failure. I read a lot of code that uses the first. I always use the second.

(1)

do-something;

if (success) {
do-this;
do-that;
...
[many lines of stuff]
do-some-other-thing;
}
else
{
print-error-message-and-exit;
}

(2)

do-something;

if (failure) {
print-error-message-and-exit;
}

do-this;
do-that;
...
[many lines of stuff]
do-some-other-thing;

I could go on at length to try to justify my strong preference, but I won't. In the end, it's just taste.

No, I take it back, I will rationalize a little. Here are some reasons I prefer #2.

  • It's shorter overall.
  • The short alternative comes first, so you don't overlook it in the noise.
  • There's one fewer nesting level to puzzle through. This also occasionally permits longer lines without word-wrap.
  • It feels more like exception handling, and saying what I mean: A problem? Let's bail.
In Perl, the solution is even more stereotyped and easy-to-read:
do-something OR die "it didn't work";
...
In bash, I use a shell function, die(), which I wrote to let me code in the same style:
do-something || die "It didn't work"
...