Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why catch Exceptions in Java, when you can catch Throwables?

Tags:

java

We recently had a problem with a Java server application where the application was throwing Errors which were not caught because Error is a separate subclass of Throwable and we were only catching Exceptions.

We solved the immediate problem by catching Throwables rather than Exceptions, but this got me thinking as to why you would ever want to catch Exceptions, rather than Throwables, because you would then miss the Errors.

So, why would you want to catch Exceptions, when you can catch Throwables?

like image 891
Richard Corfield Avatar asked Feb 24 '09 14:02

Richard Corfield


People also ask

Are all exceptions Throwables?

Throwable is super class of Exception as well as Error . In normal cases we should always catch sub-classes of Exception , so that the root cause doesn't get lost. Only special cases where you see possibility of things going wrong which is not in control of your Java code, you should catch Error or Throwable .

Why do we use catch exception in Java?

Java try and catch The try statement allows you to define a block of code to be tested for errors while it is being executed. The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.

Why would we want to catch an exception?

Java exception handling is important because it helps maintain the normal, desired flow of the program even when unexpected events occur. If Java exceptions are not handled, programs may crash or requests may fail. This can be very frustrating for customers and if it happens repeatedly, you could lose those customers.

Why is catching exception bad?

Also when you catch all exceptions, you may get an exception that cannot deal with and prevent code that is upper in the stack to handle it properly. The general principal is to catch the most specific type you can. catch(Exception) is a bad practice because it catches all RuntimeException (unchecked exception) too.


2 Answers

From the Java API documentation:

The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch.

Errors usually are low-level (eg., raised by the virtual machine) and should not be caught by the application since reasonable continuation might not be possible.

like image 184
Ferdinand Beyer Avatar answered Sep 23 '22 01:09

Ferdinand Beyer


It all depends a bit on what you're going to do with an Error once you've caught it. In general, catching Errors probably shouldn't be seen as part of your "normal" exception flow. If you do catch one, you shouldn't be thinking about "carrying on as though nothing has happened", because the JVM (and various libraries) will use Errors as a way of signalling that "something really serious has happened and we need to shut down as soon as possible". In general, it's best to listen to them when they're telling you the end is nigh.

Another issue is that the recoverability or not from an Error may depend on the particular virtual machine, which is something you may or not have control over.

That said, there are a few corner cases where it is safe and/or desirable to catch Errors, or at least certain subclasses:

  • There are cases where you really do want to stop the normal course of flow: e.g. if you're in a Servlet, you might not want the Servlet runner's default exception handler to announce to the world that you've had an OutOfMemoryError, whether or not you can recover from it.
  • Occasionally, an Error will be thrown in cases where the JVM can cleanly recover from the cause of the error. For example, if an OutOfMemoryError occurs while attempting to allocate an array, in Hotspot at least, it seems you can safely recover from this. (There are of course other cases where an OutOfMemoryError could be thrown where it isn't safe to try and plough on.)

So the bottom line is: if you do catch Throwable/Error rather than Exception, it should be a well-defined case where you know you're "doing something special".

Edit: Possibly this is obvious, but I forgot to say that in practice, the JVM might not actually invoke your catch clause on an Error. I've definitely seen Hotspot glibly gloss over attempts to catch certain OutOfMemoryErrors and NoClassDefFoundError.

like image 42
Neil Coffey Avatar answered Sep 24 '22 01:09

Neil Coffey