Fail Fast
By: Jim Shore
Immediate and
visible failure
Some people recommend making
your software robust by working
around problems automatically.
This results in the software “failing slowly.”
The program continues working right after an
error but fails in strange ways later on.
A system that fails fast does exactly the opposite:
when a problem occurs, it fails immediately
and visibly. Failing fast is a nonintuitive
technique: “failing immediately and visibly”
sounds like it would make your software more
fragile, but it actually makes it more robust.
Bugs are easier to find and fix, so fewer go into
production.
For example, consider a method that reads
a property from a configuration file. What
should happen when the property isn’t present
A common approach is to return null
or a default value:
public int maxConnections() {
string property =
getProperty(“maxConnections”);
if (property == null) {
return 10;
}
else {
return property.toInt();
}
}
In contrast, a program that fails fast will
throw an exception:
public int maxConnections() {
string property =
getProperty(“maxConnections”);
if (property == null) {
throw new NullReferenceException
(“maxConnections property not
found in “ +
this.configFilePath);
}
else {
return property.toInt();
}
}
Imagine this method is part of a Web-based
system that’s undergoing a minor upgrade. In this
release, let’s say the developer accidentally introduces
a typo in the configuration file, triggering
the error-handling code. For the code that returns
a default value, everything will seem fine. But
when customers start using the software, they’ll
encounter mysterious slowdowns. Figuring it out
could take days of hair pulling.
The outcome is much different when we
write the software to fail fast. The instant the
developer introduces the typo, the software
stops functioning, saying maxConnections
property not found in c:\projects\
SuperSoftware\config.properties. The
developer slaps his or her forehead and spends
30 seconds fixing the problem.
Fail-fast fundamentals
Assertions are the key to failing fast. An assertion
is a tiny piece of code that checks a condition
and then fails if the condition isn’t met. So,
when something starts to go wrong, an assertion
detects the problem and makes it visible.
Most languages have built-in assertions,
but they don’t always throw exceptions.
They’re also usually pretty generic, limiting
expressiveness and causing duplication.
For these reasons, I usually prefer to
implement my own assertion class, as Figure
1 shows.
However, it’s tough to know when to
add assertions. One way to tell is to look
for comments. Comments often document
assumptions about how a piece of
code works or how it should be called.
When you see those comments, or feel
like writing one, think about how you
can turn it into an assertion instead.
When you’re writing a method, avoid
writing assertions for problems in the
method itself. Tests, particularly test-driven development,
are a better way of ensuring the correctness
of individual methods. Assertions shine
in their ability to flush out problems in the
seams of the system. Use them to show mistakes
in how the rest of the system interacts
with your method.
Full article...
Other Resource
... to read more articles, visit http://sqa.fyicenter.com/art/
|