Urban Legends and Error Handling
We have all heard those stories that begin with "I know somebody" or "I
have heard of somebody" before. You can never tell whether the story being
told is true or just an urban legend. But then again, I guess that's the
whole point of an urban legend.
I could swear that I know somebody who knows somebody who has travelled
the USA in an RV a few years back. Horror movie fans might already be
predicting a gruesome end to this story, but don't worry – nobody is
going to get hurt in this column. You can continue reading this story to
your children (as always, right?).
The tourists in their RV were on their way to Las Vegas, starting out
from south of the Grand Canyon. If you're not familiar with the area, you
may not realise that it is not possible to cross the Grand Canyon by car, a
hard limit that is non-negotiable.
So when it comes to planning your route, you are somewhat limited in the
choice of roads that you can take. Now the big mistake that the tourists
made was that they did not take into account that, due to the size of their
car, they might not be able to use every available road.
In due course, they ended up in front of an underpass which their vehicle
could not fit through. They had to back up for several hours to find an
alternative route and basically lost a whole day. Given the fact that they
were heading for Las Vegas, "the adults playground", this might have saved
them a fortune, or have cost them a fortune if they had thrown a quarter
into the slot machine and won the jackpot. You never know.
Ending up in such a situation is not the fault of the underpass: the
error, made somewhere upstream, merely shows up right when approaching the
underpass, and is usually difficult (or at least tedious) to handle.
PHP as a programming language, just like any dynamic language, may at
first appear to not need overly strict validations of data. Validation of
data, however, is directly related to error handling: If data is invalid,
this should be an error or an exception (if you write OOP code, which you
should be doing). This error needs to be handled somewhere.
In most cases a failed validation, at least from the viewpoint of the
business or domain logic, means that the application programmer has allowed
the code to pass on an invalid value. Since the application code should not
have done this, the application is probably missing validation code. The
main difference between application code and domain logic in performing
validations is that application code will usually validate all data fields,
and collect multiple "error messages", while domain logic will throw an
exception immediately on the first failed validation.
So when did the error occur in the scenario described above? The error
showed up at runtime when a user entered invalid data. However, the mistake
was in fact made far earlier, when the developer wrote the application's
validation code. And, as with all errors that are discovered late in the
process, error handling is tedious: The only way to deal with the described
problem at runtime would be to translate the exception to some kind of
"please correct this form field" message.
This way of looking at a runtime error might not feel natural to you.
Maybe this is because in real life it is such a common pattern to deal with
errors long after they occurred. Let’s create a brand new urban legend of
our own to illustrate this.
Imagine you are a truck driver on a German Autobahn, proudly driving a
gigantic 50-ton plus super-truck. You will soon reach your final destination
(on time, as usual). Not too far ahead you can see a beautiful suspension
bridge spanning across a wide river valley. You are just about to make
dinner plans when you pass a sign informing you that on the bridge, there is
a weight limit of 18 tons for individual vehicles. Wait, 18 tons? Your super
truck weighs over 50 tons. Before you hit the brakes, let us freeze the
scene and think for a moment.
A problem has just arisen, a consequence of an error that occurred much
earlier when you were planning the trip. What options are there to handle
that error right now?
You can drive on and hope that the bridge withholds the weight of your
truck. If the bridge collapses as you drive over it, you will most certainly
die, and probably leave it up to your family to buy a new bridge. This does
not sound like a good option. The bridge might hold, but since urban legends
traditionally never have happy endings ... well. Let’s just assume that you
have already spotted a police inspection right after the bridge, even if you
manage to cross the bridge, you will lose your license forever, so driving
on is absolutely out of question.
Your only option right now is to hit the brakes and stop. But what next?
You are on a highway, so you cannot just turn and go back. Driving in
reverse on an Autobahn is forbidden by law, for very good reasons. So are
you going to unload your truck, right on the Autobahn, or even dismantle it?
You might ask the police to stop all traffic and block a whole section of
the highway so that you can go back. While this might be the only viable
option, you are most certainly not going to make a whole lot of new friends
on the way. And you will probably leave your boss with an enormous bill when
the police charge you for their expenses. Guess which salary that bill is
going to be deducted from!
In real life, the only way to avoid situations like this is to be very,
very careful when planning a trip (or not to drive anywhere, which is
somehow problematic if you make a living from driving). In software
development, it is crucial that you handle any errors as soon as they occur.
This requires you to actually realize that an error has occurred. In the
above example, at some point in the planning process, the business rule
"the road has to support the vehicle" is violated. If that business rule
does not exist, you are very likely to run into serious trouble at some
point in the future. One could argue whether a violated business rule is in
fact an error – I would say it is not. The actual error occurs if
there is no rule in the first place.
To sum it up, knowing and documenting all requirements and restrictions
is the key to success. And the best documentation I can imagine is working
code, because this does not only make your specification executable, but
also guarantees that your documentation is in sync with the code and thus
This article originally appeared in Web & PHP magazine.