views:

54

answers:

3

There are lot of posts on java.lang.Error saying it should not be caught. My question is if it should not be caugth the what is the use of it. Since it is Throwable so we can catch it in try catch. I read some posts like only in some situation it should be caught, how to know these situations.

In short i want to know what can go wrong when i catch Error. What is process behind it. Why they have made Error and its Subclasses? If my app is not supposed to catch them then what catches them? Why my code cannot handle this caught Error? If i simply catch one Error and write some handling code in Catch block, won't that code run?

A: 

Similar question already answered here - http://stackoverflow.com/questions/352780/when-to-catch-java-lang-error

Basically, you should never attempt to catch it as its thrown on fairly serious issues like when your thread has dead for some reason, and is not recoverable. There are however sometimes the need to catch the error when dealing with the framework itself as stated in the above URL.

JonWillis
A: 

An Error (especially a subclass of VirtualMachineError) indicates that the JVM has encountered an internal issue - one that means that its internal state may no longer be consistent. If you catch an Error and attempt to recover, future behaviour is undefined. The reason that errors are Throwable is so they can be thrown - eg you may do it your self for errors in a native library that can't be recovered from (eg the library could have written to JVM memory, or corrupted its internal static state). The same stack walking and stack trace producing machinery is used in the case of all Throwables - it would be silly to have another mechanism to do the same thing.

Most errors in the JVM that are not VirtualMachineErrors are situations where a native library could have corrupted its static state - eg AWTError, ZipError.

However there are some rare cases where catching an Error is sane: AssertionError in a testing framework, and LinkageError where you have to deal with the absence / presence of different versions of libraries at runtime. This is a pretty rare requirement and may be better handled through reflection.

rjw
+1  A: 

All rules have exceptions (except this one).

Even if everybody say you should not, there are plenty of cases where it's totally appropriate to catch those java.lang.Error. The logic behind the rule was: "do not try to continue running your application after a fatal condition was detected". You therefore must be careful before doing something after such an error is thrown. It is possible that the system might not be able to continue its task afterward.

It might be OK for a servlet to catch OutOfMemoryError, log the error and destroy the session. Maybe the problem was with that precise session. Destroying it would restore the memory and allow other users to continue using the system. However, you should have a mechanism to track those errors in real-time in order to:

  1. Fix programming errors (AssertionError, StackOverflowError)
  2. Fix configuration errors (UnsatisfiedLinkError)
  3. Correct JVM sizing parameters (OutOfMemoryError)

This kind of handling should be done very "high" in the call stack (i.e. near the main()), where the main loop (or equivalent) is performed. I think it's not a good practice to catch Error in deep code, you should at least rethrow the error in those cases.

gawi