aspose file tools*
The moose likes Java in General and the fly likes Judicious use of exceptions Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Judicious use of exceptions" Watch "Judicious use of exceptions" New topic
Author

Judicious use of exceptions

Pho Tek
Ranch Hand

Joined: Nov 05, 2000
Posts: 761

I belong to the camp that detests using CheckedExceptions.
I'm currently designing an api, and one of the methods look like so:



As much as possible, I stick with RuntimeExceptions, specifically those inside the JDK. As you can see, I'm overloading the semantics for NoSuchElementException & shoehorned it for my own use.

If you're a user of this API, (1) Does this confuse you ? (2) Would you prefer that I subclass RuntimeException to make the code more readable e.g.


[ December 08, 2006: Message edited by: Pho Tek ]

Regards,

Pho
Ådne Brunborg
Ranch Hand

Joined: Aug 05, 2005
Posts: 208
Instead of specifying NullPointException, I suggest you throw an IllegalArgumentException (also a RuntimeException) if type is null. Nullpointers should only ever occur for unforseen reasons and not be specified in the javaDoc (IMHO).

Also consider using IllegalArgumentException instead of NuSuchElementException. Shoehorning is all well and good, but sometimes there is an easier / more appropriate way.

Pasted from javaDoc:

java.lang.IllegalArgumentException: "Thrown to indicate that a method has been passed an illegal or inappropriate argument."

java.util.NoSuchElementException: "Thrown by the nextElement method of an Enumeration to indicate that there are no more elements in the enumeration."

Otherwise, looks good. There's no need to specify subclasses of RuntimeException when you have several perfectly functional ones in the JDK.
[ December 08, 2006: Message edited by: �dne Brunborg ]

Entia non sunt multiplicanda praeter necessitatem
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
I agree with �dne about throwing an IllegalArgumentException (with a descriptive message) instead of the NoSuchElementException. However I do believe that its ok to subclass RuntimeException if in the end you get a more descriptive name than the ones in the JDK. If the philosophy is that runtime exceptions are caused by programming mistakes and that bug-free code shouldn't produce RuntimeExceptions, having a descriptive name and a well thought out message help out a lot when debugging. The idea of throwing a SequenceNotFoundException instead of a raw RuntimeException seems like a good idea to me. Why do you feel like you should limit excepptions to only those found in the current jdk?
[ December 08, 2006: Message edited by: Garrett Rowe ]

Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
Ådne Brunborg
Ranch Hand

Joined: Aug 05, 2005
Posts: 208
When I wrote "...There's no need to specify subclasses of RuntimeException when you have several perfectly functional ones in the JDK" I didn't mean that you should never subclass RuntimeException and only ever use the standard ones (although I see now that it could easily be interpreted that way).

What I meant was that you shouldn't create new ones when the existing ones are descriptive enough - in this case, a SequenceNotFoundException is not necessary as the exception is caused solely by a bad input parameter, IllegalArgumentException is good enough.

That is, if I have understood what causes said exception correctly.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Garrett]: If the philosophy is that runtime exceptions are caused by programming mistakes and that bug-free code shouldn't produce RuntimeExceptions

Though that's the "standard" idea about exceptions, it's not the philosophy here at all. Pho Tek said up front: "I belong to the camp that detests using CheckedExceptions. ... As much as possible, I stick with RuntimeExceptions, specifically those inside the JDK." There are many people who find checked exceptions tedious and cumbersome. So the idea here is to avoid them entirely, if possible, and that means that runtime exceptions are preferred for situations where others would use checked exceptions.

Moving on...

I agree with �dne that we don't have to subclass RuntimeException here - but like Garrett, I think it's preferable. In addition to being more descriptive, this makes it easier for the user to create a catch block for that specific exception. As it is now, the only way to catch the "unable to increment the sequence or obtain the current sequence" exception is by catching every other exception first and then catching RuntimeException - and hoping that there are no programming errors which cause some other RuntimeException to be thrown instead - which is not exactly guaranteed. I think it would be much friendlier to the user to allow them the option of catching this specific situation by giving it a specific name.

Incidentally when I find myself creating a custom exception that is really only ever thrown by one class in particular (as may be the case here), I often will make that exception a static nested class within the class that throws it. That way it's easier for the user to track down that exception and understand what it's used for. You can also do this with an interface, nesting a static class within an outer interface. This makes sense if the interface itself defines how an exception is to be used - the exception is in a sense part of the interface. Even though it's a concrete class.

[�dne]: Instead of specifying NullPointException, I suggest you throw an IllegalArgumentException (also a RuntimeException) if type is null. Nullpointers should only ever occur for unforseen reasons and not be specified in the javaDoc (IMHO).

Mmmm, I would agree, except that at this point there is a very extensive body of use in Java in which NPE is used to indicate a null argument. (Including in many but not all of the libraries.) So many programmers are much more used to seeing NPE rather than IAE in this situation. As a result, this is one of those areas where you can make a case for either side. Personally I'm on the fence, and OK with either use. Actually I wouldn't mind seeing a NullArgumentException which subclasses either NPE or IAE (take your pick) and is more communicative about the specific situation. Ideally this NAE would also contain the name of the argument which is null, since that's often useful in debugging.

[�dne]: What I meant was that you shouldn't create new ones when the existing ones are descriptive enough - in this case, a SequenceNotFoundException is not necessary as the exception is caused solely by a bad input parameter, IllegalArgumentException is good enough.

It doesn't sound to me like SNFE is caused by bad input. To be fair, we don't know the internals of what this method does. But I think you may have confused SNFE with NoSuchElementException. I agree that the NoSuchElementException should be IllegalArgumentException. But SNFE is for other cases, I believe: "if unable to increment the sequence or obtain the current sequence."

Come to think of it, if it's really possible that you can't increment the sequence (for any reason other than not being able to find it), then SequenceNotFoundException is a misleading name. Perhaps it should be something more generic like SequenceException, or perhaps this should be two exceptions, SequenceNotFoundException and SequenceIncrementException. Or (perhaps most likely) there's essentially no chance that the sequence can't be incremented, once it's obtained. Except numeric overflow perhaps? Well if your data type / number of digits is big enough you may be able to rule this out within any practical timeframe. Or you could throw an ArithmeticException instead. My gut feeling is that in most cases, this situation should be very unlikely, and it's not worth worrying much about. There's much greater chance you'll be unable to obtain the current sequence, especially if it's persisted somewhere like a DB or file.


"I'm not back." - Bill Harding, Twister
Ricky Clarkson
Ranch Hand

Joined: Jul 27, 2006
Posts: 131
Runtime exceptions are simply not an option, as long as people forget to read specifications, and don't test exhaustively (i.e., forever).

Exceptions themselves are hard to get right - you typically use them for things you expect to go wrong - where's the line between that and using them for flow control?

E.g., look at Integer.parseInt. It is typically used not just to get an int back, but also to tell whether the String had an integer in it. That's exceptions for flow control.

If you do use exceptions for all cases like this, then you'll find that your code looks rather complicated, and unless you disable stack traces in the JVM, it will be more than a little slow.

Another way is to return a container. The container may have a value, or it may not. You give it a function to run if it has a value, and a function to run if it doesn't, and look at the return value.

In Haskell, this is the Maybe type and it works well. In Java, methods are not first-class functions, so it's a bit harder to do, but it's certainly possible.

I'll use [] for generics, because there's no preview button:



With closures, the function will become easier to write: {int x [= "You clever person, "+x+" is an int"}

[again, [ for less-than]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Ricky's comment spawned an interesting discussion about FP, which can now be found here. Please follow up there if you are interested. Thank you.
[ December 08, 2006: Message edited by: Jim Yingst ]
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
[Jim:]Though that's the "standard" idea about exceptions, [...] the idea here is to avoid them entirely, if possible, and that means that runtime exceptions are preferred for situations where others would use checked exceptions.

You're right on, I thought about that as I was writing my response, but then I just thought maybe I was taking the post too literally and dismissed the thought. Upon further inspection, I must agree with your interpretation.

[ FP comment trimmed, see other thread - Jim ]
[ December 08, 2006: Message edited by: Jim Yingst ]
Nicholas Jordan
Ranch Hand

Joined: Sep 17, 2006
Posts: 1282
Originally posted by Pho Tek:
If you're a user of this API, (1) Does this confuse you ? (2) Would you prefer that I subclass RuntimeException to make the code more readable e.g.


Let me weigh in, Mr. Tek. I am not degreed - in computer science or anything - but I have tremendous depth of insight in the question:" Does this confuse you ? " - and am willing to tackle the problem with great fiestyness and tenacity.

Quite recently, last day or two to be exact, I eliminated about six hundred lines of exception chaining from my main() class, much to the relief of some <ahem> very seasoned commentators </ahem> at the Ranch.

Well little do they know, I subclassed exception somewhere else and called it UserException, building in there a giant string table where I could get a user message or a message for me in prototyping and alpha testing. I even went so far as to provide a constructor taking both an int and a string. While your prototyping task is probably seasoned coders or something of that general nature, a production environment, and my task is something I do not have to anticipate unseasoned coders dealing with - I do note for the record that when I try to bring up my Exception.java file, I also get C.O.R.B.A.'s exception sources unless I uncheck search sub-directories. I doubt that CORBA is slouchy about approaches, their work essentially reflects exactly the same question you ask.

I have no problem dis-ambiguating what/where, though it may take a ten minute break and a cup of coffee.

It's not whether you " subclass RuntimeException"" - camp code style seems to prefer which ever produces the least space in the source file, it is that you will have some users which are heavlily acclimatized to one approach, and others which are acclimatized to another approach. Generally these broad divisions split into two phases or dichotomies, but do you have any way to ask the question of those who will be using your work ?

I agree strongly with your approach of asking the question here - that is what this forum is for and that is why these people are here.

My reply, well thought out and based on 50,000 hours under real-world conditions where failure is not recoverable, is to try if at all possible to ask your intended consumer base what they want, phrasing the question from alpha knowledge gained here. If you cannot do that for whatever reason, do it the way that makes the most sense to you.

If your consumer is confused without being able to tell you how they want it done, there is nothing you can do but write some runLogs.

I would be able to write fast and efficiently from either approach, as long as you tell me what your approach is.


"The differential equations that describe dynamic interactions of power generators are similar to that of the gravitational interplay among celestial bodies, which is chaotic in nature."
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Judicious use of exceptions