Re: Exceptions and Error Handling
From: Rhino (rhino1_at_NOSPAM.sympatico.ca)
Date: 03/02/05
- Next message: Tilman Bohn: "Re: Exceptions and Error Handling"
- Previous message: Paul: "Re: Exceptions and Error Handling"
- In reply to: Tilman Bohn: "Re: Exceptions and Error Handling"
- Next in thread: Tilman Bohn: "Re: Exceptions and Error Handling"
- Reply: Tilman Bohn: "Re: Exceptions and Error Handling"
- Reply: Sergio: "Re: Exceptions and Error Handling"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Wed, 2 Mar 2005 15:31:54 -0500
Thank you for your interesting and thought-provoking response!
Now, if I may, I'd like to ask some followup questions to clarify some
things. (I'll toss in the odd parenthetical remark too ;-) See below for the
rest of my interspersed remarks....
Rhino
"Tilman Bohn" <myfirstname@gmx.net> wrote in message
news:slrnd2bu9o.q8b.myfirstname@urizen.tilmanbohn.com...
> In message <d0lVd.31256$Vf6.968928@news20.bellglobal.com>,
> Rhino wrote on Wed, 2 Mar 2005 10:32:31 -0500:
>
> [...]
> > First, can I confirm something with you?
> >
> > Given pseudocode like this:
> >
> > try {
> > open file
> > read file
> > write file
> > close file
> > } catch (IOException io) {
> > handle exception
> > }
> >
> > Am I right in remembering that if *any* of the statements in the try
block
> > fail on an IOException (or any subclass of IOException), the code in the
> > catch block will be executed but that there would be NO indication of
WHICH
> > of the statements had failed?
>
> No immediate indication. However,...
>
> > In other words, neither the error message, the
> > stacktrace nor anything else would tell you whether the open, read,
write,
> > or close had failed, you'd simply know that one of the statements in the
try
> > block had failed?
>
> The stack trace would normally reveal it. It is after all the trace of
> the stack of method calls at the time of the exception's occurrence.
>
You are correct. In the followup to my own original post, I mentioned that I
had done a little experiment and verified that the stackTrace does indeed
tell you which statement failed, whether it was in a try block or not. (I
was doing forcing NullPointerExceptions.)
Either that behaviour changed in the last version or two of Java or I am
misremembering a situation where I didn't appear to get ANY information
about which specific statement was at fault, more likely the latter.
> > Would I be correct in assuming that my code - error handling, logging,
> > etc. - would be better if I could indentify the specific statement that
had
> > failed rather than just being able to say "ONE of the statements in this
> > arbitrarily long try block failed but I don't know which one"?
>
> Yes, in most cases.
>
> > After all, if
> > I was the programmer, it would probably save me time if I knew that the
file
> > had been found and read without difficulty but the write had failed;
that
> > would tell me file had existed in the expected place so I wouldn't need
to
> > spend a lot of time figuring out if that was the case.
>
> The important thing is not debugging. You should debug in the privacy
> of your own office, not on your customer's site. ;-) The important thing
> is _recovery_. You might try to recover differently from a failed open()
> than from a failed read(), and differently again from a failed write().
>
Good point! I'll get follow up on that in a bit....
> > I know that I could identify the specific statement that failed fairly
> > easily by putting each statement in its own try/catch block but that
would
> > contribute to serious code bloat.
>
> Robustness against failure (for real threats) is never bloat. If,
> however, you decide to do the same in all cases anyway, then of course
> you don't need three catch statements with the same recovery code.
> (Which, in that case, I predict to be non-recovery code.)
>
Well, one of the problems here is deciding what constitutes a "real" threat
and what is not. It's also difficult to figure out how to recover from some
situations.
For instance, it is true that power failures happen sometimes and also that
hard disks crash. But what can you do to either detect or recover from
either? Obviously, at the point the power cuts out to the computer, it can't
do anything to handle the error but it might be able to detect that a
previous run had terminated abruptly and unexpectedly, possibly indicating a
power failure or disk crash or something else althogether.
Do you try to write code to cover that eventuality? I've never seen code
like that in any application. For one thing, it isn't that obvious how you
would detect or respond to that situation but I suspect the main reason is
that most people would think it just wasn't that likely that the power would
fail or the disk crash, especially if both were very rare in their own
experience so why waste time writing and testing that code?
What sort of situations do you think merit handling and what ones should get
ignored? A rule of thumb would be handy to help decide this sort of thing.
> > Is there a technique for keeping all of
> > the statements in the same try block but that would still identify the
> > specific statement that failed?
>
> That would probably be more bloated and brittle than a split
> try/catch, but you have to find the appropriate granularity on a case by
> case basis. If you control the code you're calling at that point, you
> might decide to throw different exceptions from different methods that
> you can then differentiate in separate catch clauses under one and the
> same try block.
>
I'll have to think about that some more.
I'm starting to be won over to the point of view that says a single big
try/catch block is not so bad for most cases, as long as the stacktrace
tells you where the failure took place.
> > Now, a more general group of questions. Given an exception occuring in a
> > program, what is the 'best practice' with regards to handling the
problem.
> > I'm particularly concerned with what I should tell the user and what
should
> > be logged.
>
> This is really not a Java issue but a general usability question. Some
> would say the only correct reply to the question of when to bother the
> user with an error message is `never'. It is your responsibility to
> write the program in such a way that it doesn't produce errors. Of
> course we all know that the program without bugs is a rare breed indeed,
> so a more moderate reply, taking into account the possibility of
> defects, would be to only confront the user with messages when one of
> the following two statements is true:
>
> - The program needs the user to decide between various possible courses
> of action. (Note: `Abort, Retry, Fail' is not in most cases a good
> example for this, because it normally comes up when the program messed
> up, not the user, so the program should know how to correct it. Only
> decisions meaningful to the user are valid here.)
>
Why is "abort, retry, fail" not a good example?
I can think of programs I've written where the program was trying to set up
a bunch of things and the behaviour of the program might change if some
things were not possible. Considering that the behaviour might change and
therefore annoy/confuse the user, I thought it would be a good idea to at
least advise them of the problem and I could be persuaded that I should have
given them the option of quitting altogether.
For example, in one program, I was loading a Help system. However, if the
help system couldn't be loaded - typically because the user hadn't put the
Help jar in the right place during the install - the program would detect
that and notify the user that the Help system wasn't found but that the
program would proceed without the Help. It didn't seem right to just kill
the program since the user might be very familiar with the program and quite
capable of using it without the Help. Now, I only told them about the
situation but I could easily imagine that I could have given them an
'proceed/abort/retry' decision right there.
How would YOU handle that sort of situation?
By the way, I am quite willing to acknowledge that the failure to load the
Help system in the first place probably *is* my fault: the install procedure
probably wasn't clear enough or something along those lines. But nobody's
perfect. So, how should the program respond if the Help really does fail to
load?
> - you really are in a completely unrecoverable position because of
> programming error and want to notify the user of impending doom, i.e.,
> `brace yourself, we're about to crash'.
>
> However, what is completely inappropriate is the kind of error message
> most prevalent today, which is the `Sorry Dave, I can't do that' type.
> Even if they explain why.
>
The ones that REALLY drive me crazy are the ones where you go to a web page
and just get a blank screen with no information at all. Or two lines that
display a VBScript error code with nothing that the average human being
could possibly comprehend.
A couple of times, I went to websites to try to find something and kept
getting taken back to the page I'd clicked on (or the one above it), no
matter what I did. In one case, I found out that my "sin" was that I didn't
have cookies turned on and that was the code's response in that situation.
But there was nothing ANYWHERE that actually said I needed to have cookies
turned on to use that site. There was no message when I proceeded with
cookies disabled to warn me that the site might not behave correctly.
Lastly, there was nothing resembling a message when I hit a point that the
code couldn't do it's thing because I had cookies turned off; it simply
started behaving bizarrely. That is HIDEOUS design.
I could go on at length about that kind of nonsense but I won't.
The main thing is that I am trying to build friendly systems that can be
diagnosed when things don't go as expected.
> > It seems to me that the user probably doesn't want to see stacktraces
> > but that the programmer responsible for fixing the problem would get a
> > lot from them.
>
> In fact the user doesn't want to see any error message at all. They
> feel threatened by it or even violated, and because they normally don't
> understand the implications of the given choices (what was the
> difference between `abort' and `fail' again?), also inadequate. Users
> don't want to be talked down to by an arrogant error message that
> pretends _they_ did something wrong.
>
That's also a good point. In the scenario I described above where the Help
doesn't load, I would always try to word a message fairly neutrally; I'd
always try to say something passive like "For some reason, X didn't work and
now we have to shut down" than "Hey you idiot, you messed up X and now we
have to crash!". But, as you say, they'd probably prefer not to see any
error message at all.
Of course we're all trying to write code that doesn't fail, ever, but that
doesn't often happen so we're back to figuring out what to do when things
don't go according to plan.
> > Is there a list of things that show what aspects of the
> > problem should be shown to the user and what should be communicated to
the
> > programmer?
>
> Excluding the `I'm about to crash' one, _only_ ones where the user can
> be reasonably expected to decide on an appropriate way to continue
> gracefully. If there really is only one avenue, then take that, but
> don't molest the user with it.
>
> > Also, are there any guidelines about HOW to communicate with
> > each party? For instance, when should you display a message to the user
on
> > the screen and when should you write it to the console and when should
you
> > just log it but not mention it to the user at all?
>
> Console output and log files in this context are pure debugging tools
> and don't belong in robust, well-tested production code. IMO. If you
> need them in a deployed application, you've shipped green bananas to
> your customer.
>
You're not suggesting that there shouldn't be log files, right? You're just
saying that the user shouldn't have them displayed for him when the program
fails, right? If that is the case, I think I'm okay with what you're saying.
I certainly have no problem in saying that the console should not be
routinely be written to if something goes wrong in the program.
> > Also on the subject of exceptions, I seem to recall seeing a newsgroup
post
> > that cringed at the use of System.exit() in a catch method when an
exception
> > had been detected. What is wrong with System.exit()
>
> You don't know if some other thread is doing something dangerous that
> shouldn't be interrupted right about when you call System.exit(). Maybe
> it's manipulating some file in which you save state between runs under
> an appropriate lock and will leave it in an inconsistent state if you
> kill it. Or any number of similar things.
>
You're talking about another thread in the same program, right?
Does that mean that if my current program doesn't kick off any threads other
than the usual ones - event thread, etc. - it shouldn't worry about using
System.exit()?
> > and what is the preferred alternative?
>
> Tell all your threads in a nice and cooperative way to clean up and
> exit. Of course if you've tried that and find they don't comply you will
> have to get a bit more `insistent'. ;-) But if that happens it's the
> thing with the bananas again.
>
I'm going to have to review the "nice" way to end threads. I'm afraid I
don't kick off that many special purpose threads so I don't recall all the
techniques for handling them.
> </rant>
>
Again, I appreciate your thoughts on this subject!
Maybe I overdo it a bit but I'm always questioning whether my code is as
good as it can be or whether my own limitations are keeping me from writing
really good code.
Rhino
- Next message: Tilman Bohn: "Re: Exceptions and Error Handling"
- Previous message: Paul: "Re: Exceptions and Error Handling"
- In reply to: Tilman Bohn: "Re: Exceptions and Error Handling"
- Next in thread: Tilman Bohn: "Re: Exceptions and Error Handling"
- Reply: Tilman Bohn: "Re: Exceptions and Error Handling"
- Reply: Sergio: "Re: Exceptions and Error Handling"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|