R
Rhino
I'm trying to figure out some "best practices" for error handling.
Our various recent discussions have convinced me that many error situations
should probably not be handled via Exceptions, particularly things like
input errors on GUIs. I know there is a school of thought that says
exceptions are a reasonable approach to some input errors but that seems to
be the minority opinion; most people prefer other ways.
I'm trying to understand what the best approach is for a few different
situations.
1. User input errors in a GUI.
The user has a form or panel in front of him and is asked to enter his date
of birth; despite help screens and labels advising him that the format is
year-month-day separated by dashes, e.g. 2010-05-28, he enters this
information incorrectly, e.g. 05/28/10. The code that validates the input on
the form detects this error. How should the user be notified of this error?
I'm picturing a utility class being invoked by the GUI to validate the date
since this kind of validation is going to be very routine. Obviously, the
utility method is going to format an error message that tells the user what
is wrong (in the appropriate language) but then what?
I've seen, written, or used programs where that message would be displayed
back on the input panel, typically in a position that the builders of the
system think is going to be the most readily seen, like just above the input
panel or just below it. Often, you would flag the particular input field
that is in error. This feels rather 'old school' at this point but the basic
design is tried and true and it worked pretty well.
I've seen, written, or used programs where an error message popped up on in
its own window, advising the user what the error is. (Of course, this
approach needs a bit of care since you want to make sure that the message
isn't modal so that the user can see the message but also the input field so
that he can grasp the error. And you want the error window to be movable so
that it isn't frozen in one position and covering the input field that is in
error.)
Which of these do very experienced Java developers prefer? Or is there a
different approach that is better than these? I'm mostly concerning with
Java applications today, as opposed to applets or servlets, but I write all
of those types so I'm interested in the best way of error handling for all
types of Java programs.
And what would the code in the method that detects the error look like? I'm
picturing if statements that test the input and then format a message if an
error is seen. But what actually gets returned to the calling class?
Presumably, the method that edits the date was going to return a boolean
indicating if the data is good or not but how does the error message get
back to the caller? (At one point, I was writing edits like this to return
an array of Objects; the array always started with the boolean that says if
the data was good or not and, if the data was bad, the second Object would
be an error message. If the data was good though, only the boolean was
returned. Is that a good or bad design? It _felt_ wrong and forced the
calling class to parse the array but it worked okay.)
Also, am I correct in thinking that errors of the kind I am describing
should not be logged, even at a very detailed level, since the log should
only be for serious things that would involve a system administrator? (I'm
tempted to argue that the log _could_ be a place where user errors get
recorded so that people managing the users know which of their people are
having a lot of errors so that remedial training might be provided but I
suspect you will persuade me that that kind of requirement should be handled
differently.)
2. Bad input errors from a process which doesn't use a GUI.
One of my projects writes resumes to files for eventual placement on a
website. The classes that write the resumes use various utility classes to
write the resume files but there is no GUI involved. The classes make
frequent use of various utility classes that help with issues like
formatting. My project classes invoke the methods in the utility classes and
sometimes I make mistakes in invoking the method in the utility class.
Typically, it's because I've made a typo or forgotten the range of
acceptable values for a parameter to the method. So, let's say I'm going to
invoke a method that causes text to wrap on the page of a document and I've
specified one of the parameters incorrectly, perhaps the width in characters
of the available space. When I run my resume-generating class, that method
invocation is going to fail because the wrapping method is going to detect
that I've given it invalid input but there is not going to be a GUI on which
to display the message for that error. So how should that be handled?
Frankly, I feel a little odd in asking about this type of error because they
are essentially programming errors, not runtime-type errors. Basically, the
user of the class didn't understand the method that was being invoked well
enough to avoid coding unreasonable parameters in the invocation. But these
kinds of things do happen so maybe it's not ridiculous to mention them. Or
should I just assume that test cases will find these errors so that they can
be rectified during development and that it's not necessary to design for
this kind of situation.
Again, I'm assuming that errors like this shouldn't be logged.
3. Serious errors causes by programmer error.
Consider this example. Let's say that I have a method which tries to obtain
a resource bundle given input parameters like the "base name" of the
resource bundle. This base name is simply a String typed by a programmer but
the programmer recently made some coding changes and misspelled the base
name during those changes. This is rather similar to the second type of
error I just raised but this time, the consequences of the problem are a lot
more severe. Without a correctly-spelled base name, much of the information
needed by the classes won't be found and the classes are basically dead in
the water. But it is still just a programmer error: somebody mistyped the
base name.
Should there be any specific error handling within the method that looks for
the resource bundle or is it reasonable to code it as if it will inevitably
work and then assume that unit testing will catch it if the base name is
misspelled?
Should this type of error be logged? If this error will prevent the rest of
the classes' work from proceeding satisfactorily, do I just System.exit()
with a message on the console or are there better things to do?
4. Really bad errors not caused by the programmer.
A routine method in a class somewhere tries to find a file on a server
somewhere and the file is inaccessible because someone messed with file
permissions. Or a method tries to access information on a server and the
server is down for some reason. Or any of umpteen other things beyond the
control of the programmer takes place but makes it impossible for the class
to carry on.
I assume that ALL such situations should be logged. (Some of them will
surely be so obvious that the logging is redundant - every resource you're
trying to get from your server in Chile is unavailable and CNN just
announced an earthquake close to the server's location - but many are likely
to be more subtle and would not automatically be noticed by system
administrators with a nudge from the logs.)
What notifications should users receive in such cases? What notifications
should batch programs make in those cases?
Overall, I'm trying to figure out what situations need error messages, who
should see those messages and where they should be written. (Also, what
situations would call for me to write to the console? Who would normally see
the console output from a production application?)
Sorry for asking yet another "big" question but I need this kind of
knowledge to make my code more acceptable than it is....
Our various recent discussions have convinced me that many error situations
should probably not be handled via Exceptions, particularly things like
input errors on GUIs. I know there is a school of thought that says
exceptions are a reasonable approach to some input errors but that seems to
be the minority opinion; most people prefer other ways.
I'm trying to understand what the best approach is for a few different
situations.
1. User input errors in a GUI.
The user has a form or panel in front of him and is asked to enter his date
of birth; despite help screens and labels advising him that the format is
year-month-day separated by dashes, e.g. 2010-05-28, he enters this
information incorrectly, e.g. 05/28/10. The code that validates the input on
the form detects this error. How should the user be notified of this error?
I'm picturing a utility class being invoked by the GUI to validate the date
since this kind of validation is going to be very routine. Obviously, the
utility method is going to format an error message that tells the user what
is wrong (in the appropriate language) but then what?
I've seen, written, or used programs where that message would be displayed
back on the input panel, typically in a position that the builders of the
system think is going to be the most readily seen, like just above the input
panel or just below it. Often, you would flag the particular input field
that is in error. This feels rather 'old school' at this point but the basic
design is tried and true and it worked pretty well.
I've seen, written, or used programs where an error message popped up on in
its own window, advising the user what the error is. (Of course, this
approach needs a bit of care since you want to make sure that the message
isn't modal so that the user can see the message but also the input field so
that he can grasp the error. And you want the error window to be movable so
that it isn't frozen in one position and covering the input field that is in
error.)
Which of these do very experienced Java developers prefer? Or is there a
different approach that is better than these? I'm mostly concerning with
Java applications today, as opposed to applets or servlets, but I write all
of those types so I'm interested in the best way of error handling for all
types of Java programs.
And what would the code in the method that detects the error look like? I'm
picturing if statements that test the input and then format a message if an
error is seen. But what actually gets returned to the calling class?
Presumably, the method that edits the date was going to return a boolean
indicating if the data is good or not but how does the error message get
back to the caller? (At one point, I was writing edits like this to return
an array of Objects; the array always started with the boolean that says if
the data was good or not and, if the data was bad, the second Object would
be an error message. If the data was good though, only the boolean was
returned. Is that a good or bad design? It _felt_ wrong and forced the
calling class to parse the array but it worked okay.)
Also, am I correct in thinking that errors of the kind I am describing
should not be logged, even at a very detailed level, since the log should
only be for serious things that would involve a system administrator? (I'm
tempted to argue that the log _could_ be a place where user errors get
recorded so that people managing the users know which of their people are
having a lot of errors so that remedial training might be provided but I
suspect you will persuade me that that kind of requirement should be handled
differently.)
2. Bad input errors from a process which doesn't use a GUI.
One of my projects writes resumes to files for eventual placement on a
website. The classes that write the resumes use various utility classes to
write the resume files but there is no GUI involved. The classes make
frequent use of various utility classes that help with issues like
formatting. My project classes invoke the methods in the utility classes and
sometimes I make mistakes in invoking the method in the utility class.
Typically, it's because I've made a typo or forgotten the range of
acceptable values for a parameter to the method. So, let's say I'm going to
invoke a method that causes text to wrap on the page of a document and I've
specified one of the parameters incorrectly, perhaps the width in characters
of the available space. When I run my resume-generating class, that method
invocation is going to fail because the wrapping method is going to detect
that I've given it invalid input but there is not going to be a GUI on which
to display the message for that error. So how should that be handled?
Frankly, I feel a little odd in asking about this type of error because they
are essentially programming errors, not runtime-type errors. Basically, the
user of the class didn't understand the method that was being invoked well
enough to avoid coding unreasonable parameters in the invocation. But these
kinds of things do happen so maybe it's not ridiculous to mention them. Or
should I just assume that test cases will find these errors so that they can
be rectified during development and that it's not necessary to design for
this kind of situation.
Again, I'm assuming that errors like this shouldn't be logged.
3. Serious errors causes by programmer error.
Consider this example. Let's say that I have a method which tries to obtain
a resource bundle given input parameters like the "base name" of the
resource bundle. This base name is simply a String typed by a programmer but
the programmer recently made some coding changes and misspelled the base
name during those changes. This is rather similar to the second type of
error I just raised but this time, the consequences of the problem are a lot
more severe. Without a correctly-spelled base name, much of the information
needed by the classes won't be found and the classes are basically dead in
the water. But it is still just a programmer error: somebody mistyped the
base name.
Should there be any specific error handling within the method that looks for
the resource bundle or is it reasonable to code it as if it will inevitably
work and then assume that unit testing will catch it if the base name is
misspelled?
Should this type of error be logged? If this error will prevent the rest of
the classes' work from proceeding satisfactorily, do I just System.exit()
with a message on the console or are there better things to do?
4. Really bad errors not caused by the programmer.
A routine method in a class somewhere tries to find a file on a server
somewhere and the file is inaccessible because someone messed with file
permissions. Or a method tries to access information on a server and the
server is down for some reason. Or any of umpteen other things beyond the
control of the programmer takes place but makes it impossible for the class
to carry on.
I assume that ALL such situations should be logged. (Some of them will
surely be so obvious that the logging is redundant - every resource you're
trying to get from your server in Chile is unavailable and CNN just
announced an earthquake close to the server's location - but many are likely
to be more subtle and would not automatically be noticed by system
administrators with a nudge from the logs.)
What notifications should users receive in such cases? What notifications
should batch programs make in those cases?
Overall, I'm trying to figure out what situations need error messages, who
should see those messages and where they should be written. (Also, what
situations would call for me to write to the console? Who would normally see
the console output from a production application?)
Sorry for asking yet another "big" question but I need this kind of
knowledge to make my code more acceptable than it is....