Fog Creek Software
Discussion Board




Exceptions revisited

Exceptions Revisited...

Awhile back Joel wrote an article on exceptions.  He took a lot of heat for it, but I'm tending to agree with him more and more.  I must be getting older, because the more time I spend in this industry, the more I remind myself of the "Luddites" I resented when I first started out, but anyway ...

Here's my current example of exception overkill from Java library:

java.io.InputStream.readFully(byte[] b)

Here's the 1.4.2 javadoc

public void readFully(byte[] b)
              throws IOException

Reads some bytes from an input stream and stores them into the buffer array b. The number of bytes read is equal to the length of b.

This method blocks until one of the following conditions occurs:

b.length bytes of input data are available, in which case a normal return is made.

End of file is detected, in which case an EOFException is thrown.

An I/O error occurs, in which case an IOException other than EOFException is thrown.

If b is null, a NullPointerException is thrown. If b.length is zero, then no bytes are read. Otherwise, the first byte read is stored into element b[0], the next one into b[1], and so on. If an exception is thrown from this method, then it may be that some but not all bytes of b have been updated with data from the input stream.

Parameters:

b - the buffer into which the data is read.

Throws:

EOFException - if this stream reaches the end before reading all the bytes.

IOException - if an I/O error occurs.
===================

The problem is the EOFException.  This is a normal use case for the function.  Often you want to call readFully in a loop until EOF.  Normal program flow requires an exception handler for the EOF.  The handler is taken out of the program's main flow control, and the user must take the performance penalty of the exception. 

I am calling this function from a Servlet.  Nearly every time I call the function an exception is thrown.  This breaks the fundamental axiom that exceptions should be thrown in exceptional cases.  Obviously if the exception is thrown in every normal use case, then this is not an exceptional case.

I believe exceptional cases are pretty rare, and when they do occur, there often is very little that can be done.  What typically ends up happening is that exceptions become an expensive flow control mechanism.  One that is easily replaced by the common if statement.

I think exceptions should be put into same realm as go to and inheritance.  Every use should be justified.

christopher baus (www.baus.net)
Wednesday, March 24, 2004

I disagree!

The function name is "ReadFully" which I would assume is to fully read the data into the byte array.  Thus the end of file is unexpected and is an exception.

My question to you is: If the read fails with an EOF, how do you know how many bytes were read?  In the byte array, when do you know what is good data and what is garbage?

For you usage, this function is entirely wrong but not it's use of exceptions.  Ideally, there should be a function that returns the number of bytes actually read.  If that number is < the size of the byte array then we know we've reached the end of file.  Then you'd know also what is good and bad data in the byte array.

Almost Anonymous
Wednesday, March 24, 2004

Too bad that function doesn't exist in the DataInput interface.

christopher baus (www.baus.net)
Wednesday, March 24, 2004

Why don't you drop your DataInputStream into a BufferedInputStream, and read from that using the read function?

Elephant
Wednesday, March 24, 2004

Yes ok, that is the correct way to do.  I guess I'm getting too grumpy in my old age ; ). 

The function I'm looking for is DataInputStream.read();

christopher baus (www.baus.net)
Wednesday, March 24, 2004

.NET throws a similar exception. To avoid it, I call a method (get a property) see how many bytes are in the file, and don't attempt to read more than that many bytes.

Christopher Wells
Wednesday, March 24, 2004

Having gotten seriously into Java over the last couple years, the advice I always give to newcomers (and grumpy old farts such as yourself :) is to defer judgement on how stupid it all is until you've found the right javadoc.

That's the flaw with a huge (and sometimes inconsistent) standard library: it's easy for a programmer to naively do the wrong thing because it's so damn hard to find the right thing to do in the literature.  For just about every situation I've come across with Java, there's a nice, clean, simple way to do it, but the amount of labour I spend finding that way in the javadocs and tutorials can be astonishing.

Justin Johnson
Wednesday, March 24, 2004

Justin-

true, but on the other hand it's nice that the nice clean way of doing things is there in the first place.  The real trick is when you are used to doing things one way and a new version of Java comes out with a better way of doing things (example: the new image io stuff).  It may never occur to you to jettison the old hacks you used to do.

name withheld out of cowardice
Wednesday, March 24, 2004

I think the OP did have a good point to some extent, while exceptions and exception handling are a good thing, I do think Java goes overboard with checked exceptions versus unchecked ones. For example, do the various JDBC interfaces really need to throw a checked SQLException on the close() methods versus an unchecked one?

Gerald
Wednesday, March 24, 2004

Don't get me wrong: I'm very happy coding Java.  But that's the single largest source of my frustration.

Justin Johnson
Wednesday, March 24, 2004

I've always liked [ http://java.sun.com/docs/books/chanlee/ ].  Gives good examples and overview of class libs, but in a fast javadoc-like way.

I agree that exceptions aren't great.  It's not like they're the state of the art.  I wish people didn't attack Joel so harshly because there are big problems with exceptions.  They bust through stack.  Ironically though, Joel attacked lisp, which has the solution.  Without depending on any sort of unconventional syntax; this solution could be transported to Java/C#.

Tayssir John Gabbour
Wednesday, March 24, 2004

I think the correct conclusion about the original post was reached but I still sense uncertainty, so...

The original post demonstrated an improper use of the library, not an overzealous use of exceptions.  readFully() is from DataInput, an interface with a particular purpose: to abstract (and simplify) the reading of whole values from an underlying stream expected to hold them, as when deserializing an aggregate type.  Neither the interface nor that method are intended for general byte reading.  InputStream is for that.  Asking a DataInput to read a whole value, be it a double, an int, or a byte array of given length, from a stream that does not contain such a thing is an error, and therefore *should* throw an exception.

While the Java libraries are indeed messy, and those classes that predate JDK 1.2 are unredeemably amateurish, most of the later stuff isn't terribly bad.  (How's that for a glowing endorsement.)  When you find yourself doubting the propriety of an exception declaration, you might be right, but more likely you're probably trying to stick a square peg in a round hole as in the original post.  The JDBC close() exceptions leave room for debate, but are still perhaps the right thing, and don't cause much trouble anyway.

When you find yourself doubting the usefulness of checked exceptions in general, that's just flat out wrong.  Exceptions are an excellent construct with no deficiencies when used skillfully.  Joel's post about exceptions suggested that we throw exceptions because we have no concise mechanisms to return multiple values to the immediate caller.  That misses the point of exceptions entirely which, while perhaps too much to explain in a short post, is essentially to carry the fact of a problem back as far as necessary to whichever caller is best suited to *do* something about that problem, which is not often the immediate caller.

One final note about the square peg problem.  I recommend pursuing the Java certification, or at least studying the class libraries well enough to pass those parts of the certification relevant to your use of the language.  (Perhaps its a bit much to dive into Swing if you write only server applications.)  You'll learn corners of the libraries you might never have sought out otherwise, and you'll be forced to learn the fundamentals thoroughly.

While a doctor will sometimes research a particular technique or condition only upon needing that knowledge for a particular case, he or she shouldn't be confused about the basic function of the pancreas.  Likewise as professional programmers it is our duty to know our basic tools really well.  I know that sounds preachy, but java.io is fundamental.  In my own work, many of the most ridiculous things I've seen in code are due to spotty knowledge of the tools.  It's too easy as an experienced programmer to jump headlong into a new language and be productive without doing all the homework.

veal
Thursday, March 25, 2004

> I agree that exceptions aren't great.  It's not like they're the
> state of the art.

Since this discussion seems to be about Java you might be right in the context.

Going away from Java (like Joel did) this is horseshit.

In C++ you can use the RAII idiom + ScopeGuard by Alexandrescu and you have a "state of the art" perfectly working solution.

_
Thursday, March 25, 2004

Unfortunately, ScopeGuard is only known to the small portion of C++ devs that read C++ User's Journal reguarily.   

Here's a reference to those articles by the way:
http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm

I still stick to my guns that exceptions are often abused. 

BTW, I don't intend on seeking Java certifications, or any other cert for that matter.  I'll leave that to the law students.   

christopher baus (www.baus.net)
Thursday, March 25, 2004

It's not the certification paper that matters, but the basic knowledge one is forced to acquire during the pursuit.  The certification paper has no great value, and while an exam cannot measure programming talent, it does indicate whether one's knowledge of the programming language and libraries meets the bare minimum below which the scorn of one's colleagues is well deserved.

The practice exams in certification guide books serve just as well.

veal
Thursday, March 25, 2004

*  Recent Topics

*  Fog Creek Home