Introduction
Many times you need to check a number of error conditions for a piece of data and deal with them, before doing the right thing with that data.
Maybe you simply want to display the data on the screen, in a certain format. That sounds like one line of code, doesn't it? Not if you just read that data from an external source - you need to do error checking first.
There are many reasons to do serious error checking on data read from an external source. It keeps your program from blowing up on:
and many other situations.
Improper error handling can result in confusion for the user, failure to get work done that is critical to your project or company, or worse - corrupt data when the change could not be completed in the middle of the operation due to an unexpected error!
Things to Consider
I like to think about it this way, when reading a piece of data from a file or from the user:
What is everything that can go wrong?
By handling everything you possibly can, you write more code today, but you reduce the likelihood of problems down the road. In my experience during the past 20 years I've been programming, the tradeoff is definitely worth it.
Example
Let's say you've asked the person for their full name. (We'll use pseudo code, to try to stay platform and language independent.)
display "enter your name:"
ask user for their name, store it in variable "name"
|
That was easy. But what if they hit ENTER without typing anything? It happens. And we really don't want to continue in that case. Let's try to handle that.
display "enter your name:"
ask user for their name, store it in variable "name"
if name is empty, print "error: empty name" and exit.
|
Well, that will work, however it's not very good style. It would be better to give the person a second chance. How can you ask a question over and over, until you get good data? That sounds like a loop to me!
set errorflag = true
while (errorflag is true) {
display "enter your name:"
ask user for their name, store it in variable "name"
if name is empty, print "error: empty name, try again";
else if (another condition), print another error;
else set errorflag = false
}
|
We had to write and debug more code, but once it's working, this is a good design. It will ask over and over, because the errorflag variable is true (meaning "yes, there's an error"). As you can see, there's room for as many error conditions as you want, all of which will make the user try again. Only if we get past all the "if" statements successfully, would the errorflag ever be set false - letting us get out of this neverending looping, on to the rest of the program.
Another Example
Take a look at this chunk of code:
if (file doesn't exist or file is empty or file is not readable) {
print "file error"
exit the program
}
read file
use file
|
What is wrong with this code?
It generates a very poor error message. It's good that we're checking 3 possible error situations, but the same error message will be generated in all 3 situations. This causes confusion for the user ("WHAT is the actual problem?"), and makes it much harder for you to debug the situation when someone calls you for help when they get this error.
You're the program owner - make things easier on yourself! Use very specific error messages; separate ones for each error situation.
Rewrite That Code
OK, let's rewrite that code to be better:
if (file exists) {
if (file is not empty) {
if (file is readable) {
read file
use file
} else {
print "error: file is not readable"
exit the program
}
} else {
print "error: file is empty"
exit the program
}
} else {
print "error: file does not exist"
exit the program
}
|
OK, this is much better. 3 separate error messages, telling exactly what is wrong, for the 3 situations.
But - there's some problems with this coding method. Every error we check causes our code to indent further and further towards the right side of the screen. The meat of the code ("read file; use file") is the most-indented code. Often, that part of the code can be really long (a screenful or more of code), all having to be severely indented, leaving you little room to work, cramping your style. Not only that, but once you've written all the indented success-code, now you have to remember which indent level goes with which error message!
The error messages are really far away from the condition that handled them. If you end up changing the logic on an if-statement at the top of this mess, you may also have to tweak the error message way down at the bottom. Let's hope you change the right error message!
As you probably guessed, there's a better way.
Rewrite That Code Again
Here's the exact same logic, arranged much better:
if (file DOES NOT exist) {
print "error: file does not exist"
exit the program
}
else if (file IS empty) {
print "error: file is empty"
exit the program
}
else if (file is NOT readable) {
print "error: file is not readable"
exit the program
}
read file
use file
|
Look at how clear that is!
Everything related to each error is right there in 1 little area.
If you have to add another error condition, it will be 1 small chunk of code, amongst the other error handling code there.
The "good code" simply comes after all the error checking, and can stay un-indented for maximum screen-space for its code.
The size of the "good code" does not affect any of the error handling lines; it will not be any tougher to debug if the "good code" happens to be 300 lines long.
Summary
Find ways to keep "like things together". Handle all errors before handling the normal case.
It's especially useful to study other people's code to learn cool tricks like this.
Don't miss the latest general tips and tricks!
Subscribe to our low-volume mailing list:
Privacy Policy
| Copyright © 2006 Fastech Learning LLC, all rights reserved. |
| Phone toll free 1-866-464-6688, Phoenix Metro area 480-895-6688 |
| Problem with this web site? please let us know |