tags:

views:

379

answers:

6

I have been in both situations:

  • Creating too much custom Exceptions
  • Using too much the general Exception class

In both cases the project started OK but soon became an overhead to maintain (and refactor).

So what is the best practice regarding the creation of your own Exceptions?

+1  A: 

Basically, each job deserves an own exception. When you catch exceptions, you don't distinguish different instances, like you would normally do with objects, therefore you need different subtypes. Using too many custom exceptions is a case which I see hardly occurring.

One advice would be to create exceptions as needed, and if it becomes apparent that one exception type is a duplicate of another, refactor the code by merging the two. Of course it helps if some thought goes into structuring exceptions from the beginning. But generally, use custom exceptions for all cases that have no 1:1 correspondence to existing, situation-specific exceptions.

On the other hand, NullPointerExceptions and IndexOutofBoundsExceptions might actually often be appropriate. Don't catch these, though (except for logging) as they're a programming error which means that after throwing them, the program is in an undefined state.

Konrad Rudolph
+3  A: 

My rule of thumb is when the client (the caller) might reasonably want to do something different depending on the type of exception thrown, then additional exception types are warranted. More often then not, however, the extra exception types are not needed. For instance, if the caller is writing code like

try {
     doIt();
} catch (ExceptionType1 ex1) {
     // do something useful
} catch (ExceptionType2 ex2) {
     // do the exact same useful thing that was done in the block above
}

then clearly the additional exception types were not needed. All too often I see (or am forced to write) code like this because the code being called was overzealous in its creation of new exception types.

landon9720
+3  A: 

The Java Specialists wrote a post about Exceptions in Java, and in it they list a few "best practices" for creating Exceptions, summarized below:

  • Don't Write Own Exceptions (there are lots of useful Exceptions that are already part of the Java API)

  • Write Useful Exceptions (if you have to write your own Exceptions, make sure they provide useful information about the problem that occurred)

Josh Brown
+1  A: 

If I can't find an exception that has a name describing what type of error was caused then I make my own.

That's my rule-o-thumb.

jjnguy
A: 

My own rule of thumb:

I never throw Exception, except in unit tests when what you throw is irrelevant and theres no reason to spend any extra time on it.

I create my own custom exception type for errors occuring in my custom business logic. This exception type is used as much as possible for recasting other exceptions, except in cases where it makes sense for the client to have visibility into what actually occurred.

shsteimer
+1  A: 

Don't do what the developers at my company did. Somebody created an [sic] InvalidArguementException that parallels java.lang.IllegalArgumentException, and we now use it in (literally) hundreds of classes. Both indicate that a method has been passed an illegal or inappropriate argument. Talk about a waste...

Joshua Bloch covers this in Effective Java Programming Language Guide [my bible of first resort on Best Practices] Chapter 8. Exceptions Item 42: Favor the use of standard exceptions. Here's a bit of what he says,

Reusing preexisting exceptions has several benefits. Chief among these, it makes your API easier to learn and use because it matches established conventions with which programmers are already familiar [my emphasis, not Bloch's]. A close second is that programs using your API are easier to read because they aren't cluttered with unfamiliar exceptions. Finally, fewer exception classes mean a smaller memory footprint and less time spent loading classes.

The most commonly reused exception is IllegalArgumentException. This is generally the exception to throw when the caller passes in an argument whose value is inappropriate. For example, this would be the exception to throw if the caller passed a negative number in a parameter representing the number of times some action were to be repeated.

That said, you should never throw Exception itself. Java has a well-chosen, diverse and well-targeted bunch of built-in exceptions that cover most situations AND describe the exception that occurred well enough so that you can remedy the cause.

Be friendly to the programmers who have to maintain your code in the future.

Mark Jaeger