48

Given: Throwable is Exception's superclass.

When I read texts on writing your own 'exceptions', I see examples of Throwable being used in the catch block and other texts show new Exception() being used in the catch block. I have yet to see an explanation of when one should use each.

My question is this, when should Throwable be used and when should new Exception() be used?

Inside the catch or else block using either:

throw throwable;

or

throw new Exception();
Neuron
  • 5,141
  • 5
  • 38
  • 59
WolfmanDragon
  • 7,851
  • 14
  • 49
  • 61
  • 1
    Why do you use "new"? Are you comparing catch(Throwable) vs catch(Exception)? – Zach Scrivena Jan 31 '09 at 04:17
  • @WolfmanDragon: So you are throwing Throwable/Exception from *inside* the catch block? Are we to assume that "throwable" is an existing Throwable caught by that block? – Zach Scrivena Jan 31 '09 at 04:35
  • @Zach Scrivena: no, this was general question. I have written exceptions in C++ but never in Java, and I am a little confused. The issue that brought this up is that I need to pass an 'exception' to a piece of code a coworker is building if a collection does not get built. – WolfmanDragon Jan 31 '09 at 04:44
  • If the thing you're throwing is supposed to be meaningful, you should throw something more specific than just "Exception". Either use something that already exists (depending what the reasons are you can fail), or define your own subclass of Exception (or of one of its existing subclasses). – Steve Jessop Jan 31 '09 at 04:48

12 Answers12

46

Always throw an Exception (never a Throwable). You generally don't catch Throwable either, but you can. Throwable is the superclass to Exception and Error, so you would catch Throwable if you wanted to not only catch Exceptions but Errors, that's the point in having it. The thing is, Errors are generally things which a normal application wouldn't and shouldn't catch, so just use Exception unless you have a specific reason to use Throwable.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Ray Hidayat
  • 16,055
  • 4
  • 37
  • 43
  • 8
    Dont throw exception, throw the appropriate Exception sub class or your own. The whole point of Exception having sub classes is that different types of problems can have their own exceptions. In addition to including the message and possibly wrapping the cause exception one can add extra "data". – mP. Jan 31 '09 at 04:34
  • Yeah, that's what I meant, throw a subclass of Exception. Sorry wasn't thinking hard enough. – Ray Hidayat Jan 31 '09 at 04:39
  • 2
    this is the correct answer. the asker has made an unfortunate choice for which one to mark correct. also see cHao's comment on a different answer above which complements this one nicely. – necromancer Apr 29 '13 at 21:17
17

(from comments) The issue that brought this up is that I need to pass an 'exception' to a piece of code a coworker is building if a collection does not get built.

In that case, you might want to throw a checked exception. You could throw an Exception, an appropriate existing subclass of it (except RuntimeException and its subclasses which are unchecked), or a custom subclass of Exception (e.g. "CollectionBuildException"). See the Java Tutorial on Exceptions to get up to speed with Java exceptions.

Zach Scrivena
  • 29,073
  • 11
  • 63
  • 73
  • While your answer answers my comment, I still don't understand why some of the big names in the field say to throw Throwable (Hardcore Java By Robert Simmons, Jr.) while others say never to use Throwable. Hardcore Java happens to be the besst java book ever, except in this one case. – WolfmanDragon Feb 03 '09 at 22:12
  • 3
    Throwable is the superclass of Exception and Error. Of the three classes, I would consider Exception to be the most suitable one for the task. Most people write try-catch blocks that look out only for Exception and its subclasses; they will not be able to handle a new Throwable(). – Zach Scrivena Feb 03 '09 at 22:28
  • (cont'd) unless there is a "catch (Throwable t)" too. – Zach Scrivena Feb 03 '09 at 22:30
  • 14
    i like how you completely avoided the central aspect of the question: whether to use throwable or exception as the base when throwing an exception. i also like how the asker accepted it as the correct answer. – necromancer Apr 29 '13 at 21:14
  • @no_answer_not_upvoted: read it again. It's sort of subtle, but it's there. – Mooing Duck Nov 15 '13 at 21:32
10

You should not really catch an exception and throw a new one as general as "new Exception".

Instead, if you wish to bubble up the exception just do the following:

try {
    // Do some stuff here
}
catch (DivideByZeroException e) {
    System.out.println("Can't divide by Zero!"); 
} 
catch (IndexOutOfRangeException e) { 
    // catch the exception 
    System.out.println("No matching element found.");
}
catch (Throwable e) {
    throw e; // rethrow the exception/error that occurred
}

It is not good practise, I believe, to catch an exception and throw a new exception instead of the one that was raised to your code block, unless you raise a useful custom exception that provides enough context to elude to the cause of the original exception.

MichaelD
  • 195
  • 7
  • 3
    This code would discard the DivideByZero and IndexOutOfRange exceptions. Logging the exception before throwing it is generally a bad idea. If an exception is logged at all, it is usually best to do it at the level in the stack that is responsible for truly handling the error, without re-throwing. – erickson Feb 01 '09 at 03:41
  • 2
    The code is meant to address the questioner's question. Best practises that don't affect the questioner's question is out of he scope of this answer. I just want to show that you can address exception cases but still rethrow the exception if an exceptional exception has occurred. – MichaelD Feb 01 '09 at 12:57
  • @erickson You mean Logging the exception `without` throwing it is generally a bad idea. ? – Koray Tugay Jul 30 '17 at 14:11
  • @KorayTugay No, I mean if you are re-throwing an exception, you should not log it. That is likely to cause the same problem to be logged multiple times. Only log where you stop the exception's propagation. – erickson Jul 30 '17 at 22:55
5

Only two places you should see the word Throwable in code:

public static void main(String args[])
{
     try
     {
         // Do some stuff
     }
     catch(Throwable t)
     {

     }
 }

AND

public class SomeServlet extends HttpServlet
{
      public void doPost(HttpRequest request, HttpResponse response)
      {
         try
         {
             // Do some stuff
         }
         catch (Throwable t)
         {
              // Log
         }
      }
 }
uranazo
  • 51
  • 1
  • 1
  • 5
    Even these two would be at least one too many, IMO. Catching `Throwable` (especially outside of `main`) is a recipe for disaster, as you're casting way too wide a net. More than just app-level exceptions are Throwable. Common example: OOM Errors. How are you going to log them, if the very act of writing of a log causes an object to be created (read: allocated, by the very process that just failed)? And when that *does* fail, what now? You've lost the info that caused the original error, because you've caused a new one that'll be propagated instead. That's if the app doesn't just die. – cHao Apr 13 '11 at 11:58
4

Oracle gives the answer in its official tutorial ("How to Throw Exceptions").

First it explains that Throwables is a union of Error and Exception classes, which are 2 different things.

Throwable = Error + Exception

Next, it makes clear that an Error is something extremely rare, that is almost impossible to recover from.

When a dynamic linking failure or other hard failure in the Java virtual machine occurs, the virtual machine throws an Error.

And putting 1+1 together, it politely concludes, that (except for simple Exceptions) there is no point in catching other Throwables, since you can't do anything about them.

Simple programs typically do not catch or throw Errors.

bvdb
  • 22,839
  • 10
  • 110
  • 123
2

Throwable is an interface, not a class. Two classes extend Throwable, Exception and Error.

The rule is: be as specific as you can when catching exceptions - that means for example catching Exception instead of Throwable, and IOException instead of Exception.

Don't catch Errors - errors are bugs. Fix the code instead.

If you have to catch absolutely everything, use "catch Throwable", but this is bad form.

Michiel de Mare
  • 41,982
  • 29
  • 103
  • 134
  • Throwable is a concrete class too. – Zach Scrivena Jan 31 '09 at 04:22
  • Hey, actually I had been under the impression Throwable was an interface until I looked. Not sure why this is or if this is a new thing. – Ray Hidayat Jan 31 '09 at 04:24
  • Thanks for pointing that out - I guess I was misled by the -able suffix. – Michiel de Mare Jan 31 '09 at 04:46
  • Errors are hardly bugs that can be fixed in java code where they appear. They might be fixed by altering the environment (such as memory limits) or deployment (when a class is missing or wrong version) but very rarely by changing the code where they are thrown. – Jacek Szymański Jan 31 '09 at 08:58
2

throw new Exception(); is something you should never do in a catch block, but you may have to or want to do throw new SomeException(throwable); (preserving the full stack trace) instead of throw throwable; in order to conform to the API of your method, e.g. when it declares to throw SomeException but you're calling code that might throw an IOException that you don't want to add to you method's throws clause.

The probably most common case is new RuntimeException(throwable); to avoid having a throws clause altogether. Many people will tell you this is a horrible abuse because you should be using checked exceptions. IMO they are wrong and checked exceptions are a mistake in the Java language design that just results in ugly, unmaintainable code.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • 1
    Unchecked exception are a common cause of "leaky abstractions". http://www.joelonsoftware.com/articles/LeakyAbstractions.html They are fine for one-size-fits-all error reporting--useful in many cases--but they can't support true exception handling in the face of abstraction. – erickson Feb 01 '09 at 03:48
1

Generally, you would not throw or catch Throwable. In particular, JVM errors (that extend Error() ) are not meant to be caught by user code unless you are doing weird system-level work.

Treat "Throwable" as a language artifact. The "Exception" class is named that because it is the one that is intended to be used by programmers when they want a code block to exit "exceptionally" - by not exiting normally or returning a value.

That includes both regular error situations (by "regular" I mean as opposed to JVM errors) and places where you are using exceptions as a control mechanism.

0

You shouldn't use Exceptions as a "return type" either...

If the condition you're throwing for is common, you are spending a huge amount of resources to return that condition to the calling routine. Exceptions are expensive to construct.

I've seen cases where tight loops that threw exceptions as a "negative" for e.g. ID allocation, this routine occupied about 99% of the CPU time .. when changed to a documented return constant instead, this dropped to 25%.

Adrian
  • 2,244
  • 18
  • 20
0

As I heard it when java first came out, the theory was that Throwable might be used for transfer of control in other cases besides exceptions. I've never seen it used that way though (and that's probably a Very Good Thing).

So just catch Exception (or better yet, a more fine-grained exception).

Bill K
  • 62,186
  • 18
  • 105
  • 157
0

Throwable is meant to be only caught by the container or main loop of your program. Most of the time catching stuff below Exception eg Error does not add much capability to a program, after all what can you possible do if a VirtualError other Errors are thrown. Not much except log and continue.

mP.
  • 18,002
  • 10
  • 71
  • 105
  • So use throwable if it is to be passed to the main or servlet to make logic decision? new Exception() if it is just to be logged? – WolfmanDragon Jan 31 '09 at 04:36
0

All exceptions are a problem in the end... too say Errors are bugs doesnt mean anything.

Errors are not bugs - they are problems that the host VM is experiencing, eg OutOfMemoryError. Exceptions are a means that the current operation may use to notify that it failed and perhaps provide some diagnosis.

mP.
  • 18,002
  • 10
  • 71
  • 105