I have a class the implements A
which will run a certain method of class B
. There is a requirement that this A
should never crash when running this operation (which is not possible, right?).
To reduce the chance of crashing I’m catching Throwable
around the operation, like so:
public void method(B b)
{
try
{
b.operation
}
catch(Throwable e)
{
//Log e
//Clean up stuff
}
}
My questions are:
- Would this actually help in reducing crashes caused by any thrown
Error
? - Is it a good idea to ever catch an
Error
?
7
Simple Answers: No and no.
For example catching an OutOfMemoryError
can be bad as without memory what could you do?
Also all other errors are most likely indicate some more serious error where you can do nothing.
For reference see the errors in the package java.lang and decide for every one what you will do when you catch it. If you’re happy you will find that perhaps every tenth error could be handled by you.
12
When you encounter an Error
, it typically means your program is now in an undefined state: a .class
file is corrupted, or memory is completely full, or you’ve run into an internal bug in the JVM, or something of similar severity. Ask yourself: even if you catch the Error
to prevent an immediate crash, is it meaningful to continue running under these circumstances? Can you trust the program to behave correctly afterward? What can you do to actually handle an Error
once you catch it?
If your “never crash” requirement means “never stop executing”, then by all means, log and continue. Clearly your client believes that a misbehaving program is better than a terminated one. But if “never crash” means “never stop functioning”, you should focus your defensive efforts elsewhere to prevent the Error
from occurring in the first place, let it terminate the program if it somehow occurs anyway, and configure your server to automatically restart the program if that happens.
In general, you should NEVER catch things like Exception, Throwable, or Error, but only those specific subclasses of those that your application can reasonably be expected to handle and survive (or at least log something useful about before crashing).
Exception handling is supposed to be just that, handling error conditions and dealing with them in such a way that the application can continue running or report what happened before terminating.
It’s not meant to be error masking, hiding problems and then just try to continue as if nothing happened. Not only will it rarely work (it will rear its ugly head somewhere else in the application soon, making the problem worse as now you have even more corruption in your state and/or data, but you now have a problem that’s that much harder to track down and debug, and eventually fix.
I won’t write a java program without catching Throwable at the
top level of every process. The caught error is (by definition)
unexpected, and is a bug that needs to be logged and fixed. The
errors you catch this way will surprise you, and you will never
learn of them unless you make every possible attempt to get the
word back from the real world to your development desk.