views:

2794

answers:

10

At what point would you create your own exception class vs. using java.lang.Exception? (All the time? Only if it will be used outside the package? Only if it must contain advanced logic? etc...)

+17  A: 

I think you need to ask yourself a slighly different question "What advantage does creating a new exception give me or developers who use my code?" Really the only advantage it gives you or other people is the ability to handle the exception. That seems like an obvious answer but really it's not. You should only be handling exceptions that you can reasonably recover from. If the exception you throw is a truly fatal error why give developers a chance to mis-handle it?

More in depth discussion: Custom exceptions: When should you create them?

JaredPar
Also create one if you don't want to confuse the user.. java.lang.Exception could mean a zillion things that could have gone wrong.. be specific with e.g. AppFileNotFound(sFilePath) - helps cut down beating around the bush...
Gishu
+5  A: 

When I want to treat my exceptions differently from everybody else's. If I want to catch mine and propagate everyone else's, or if I want to catch someone else's and propagate mine, or if I want to catch both but treat them differently, then I will define a separate class for my exceptions. If I want to treat them all the same, either by propagating both or by catching both (and doing the same thing either way with the caught exceptions), the I will use the standard class.

Glomek
A: 

In most cases it doesn't make sense to create your own exception class.

There is a tendency in novice programmers to create their own exception class just so they can use a name that is more indicative of the type of error. So you'll find classes like FTPInitializationException, DAOFactoryException etc. even though such exceptions are not being handled differently than standard exceptions. This is clearly an anti pattern that should be avoided.

Rahul
Advising that programmers throw an java.lang.Exception is much worse than throwing their own class than extends java.lang.Exception; there are many exceptions that extend j.l.Exception that should not be caught.
janm
+1  A: 

Start always by using the common exception classes and then when a need appears to handle it specially, change it.

  1. When creating a method first time, just let exceptions go through.

  2. If there are exceptions that must be handled, those can either be just defined in throws or wrapped to some runtime exception or wrapped own throws exception. I prefer runtime exceptions in many cases. Defining throws definition should be avoided until there is a need for it from API point of view.

  3. Later when a need appears to do specific handling for an exception in some caller, come back and create new exception for it.

The point is to avoid doing extra work before knowing what is needed.

iny
The Exception class is special; "catch (Exception e)" will catch all kinds of things that you probably shouldn't be catching.
janm
I'm not saying to catch it. That "common exception classes" could mean even your own common exception. The point is to avoid creating specific classes before there is need for them.
iny
I think it is worth making that clear in your answer; the only "common exception class" in the question was java.lang.Exception; using that is bad. If you have "throws Exception" in your exception spec then callers are forced to deal with everything.
janm
The advice you added is good; my point is that java.lang.Exception is special and should be treated with care.
janm
@janm - Yes, throwing java.lang.Exception requires defining it in throws and so the point of throws is lost, but using throws well is anyway hard, so just use runtime exceptions. :)
iny
Sure, I agree that using classes that extend RuntimeException is better. However, the classes that you throw as exceptions are part of your interface contract, and using j.l.Exception there is bad. The question was about j.l.Exception, and the answer should be "don't use it!"
janm
+6  A: 

IF there is an existing Exception with the language runtime or libraries, use it ELSE create your own, document it well and that should work in 99% of the cases.

anjanb
+7  A: 

Reason one:

Need to catch specific stuff. If calling code needs to deal with a specific exceptional condition, you need to differentiate your Exception, and Java differentiates exceptions with different types, so you need to write your own.

Basically, if someone has to write:

catch(ExistingException e) {
  if({condition}) {
    { some stuff here}
  }
  else {
    { different stuff here}
  }
}

You probably want to write a specific extension; catch Exception matching is clearer than conditionals, IMHO.

Remember: your new Exception can be a subclass of RuntimeException

Reason two:

API consolidation. If you write an interface and you have several implementations, it's possible that they will call different APIs with a whole bunch of different non-RuntimeExceptions thrown:

interface MyInterface {
  void methodA();
}

class MyImplA {
  void methodA() throws SQLException { ... }
}

class MyImplB {
  void methodA() throws IOException { ... }
}

Do you really want MyInterface.methodA to throw SQLException and IOException? Maybe then it makes sense to wrap the possible exceptions in a custom Exception. Which again can be a RuntimeException. Or even RuntimeException itself...

alex
A: 

I would use the exceptions from the Java API when the exception relates to the API. But if an exceptional situation arises that is unique to my own API then I will create an Exception for it. For example if I have a Range object with two properties min and max and the invariant min <= max then I will create an exception InvalidRangeException.

When I am writing code this helps because I know if the exception originates because I violated one of my own conditions or its something from the Java API.

Vincent Ramdhanie
+4  A: 

I believe that:

catch (Exception e) {
   ...
}

... is an antipattern that should be avoided. You might want one centralized broad catch somewhere in your application, to log an error and prevent the whole application from terminating - but having them scattered around willy-nilly is bad.

Why:

try {
   if(myShape.isHidden()) {
      throw new Exception();
   }
   // More logic
} catch (Exception e) {
   MyApp.notify("Can't munge a hidden shape");
}

So you try this, and due to a coding error, myShape is null. A NullPointerException gets thrown when the runtime tries to derefence myShape. This code reports a hidden shape, when it should be reporting a null pointer.

Either make your own exception, or find a suitably specialized exception in the API. It's not as if extending Exception or RuntimeException is onerous.

slim
You can do `throw new Exception("Can't munge a hidden shape"); ... MyApp.notify(e.getMessage())`. Which is far more readable and manageable.
brice
+1  A: 

I can't imagine specifically throwing a java.lang.Exception if some object/class/method had a problem. It's too generic - if you're not going to create your own Exception class, seems to me like there ought to at least be a more specific Exception-type in the API.

matt b
+1  A: 

Software captures meaning.

There are almost no reasons for throwing an existing exception: the JVM already does that for you. Your version of their exception isn't really accurate and throwing "Exception" isn't meaningful, either.

You might have a DataFormatException because of a parsing algorithm you wrote. This, however, is rare.

When your program encounters an exceptional situation, it's almost always unique to your program. Why force-fit your exceptional situation into an existing exception? If it's unique to your program, then... well... it's unique. Name it that way.

Do not, however, provide a unique exception class for each unique message. One exception class can have many variant messages and supporting details.

The Python rule of thumb, translated to Java, is to define any unique exceptions at the package level. [In Python, they suggest exceptions at the "module" level, something that doesn't precisely translate to Java.]

S.Lott