3

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?
gnat
  • 21,213
  • 29
  • 113
  • 291
Adam
  • 295

4 Answers4

11

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.

Uwe Plonus
  • 1,310
  • But are there any other Errors that can be "handled"? – Adam Oct 06 '14 at 14:22
  • 3
    @Adam No, there are none. One of the reasons they are not exceptions is stated right on the Error class - reasonable applications should not catch these. Another trait is that Errors are not local. For most exceptions all side effects are in the calling method, for an Error that is not the case. – Ordous Oct 06 '14 at 14:24
  • @Adam extended answer while you created the comment. – Uwe Plonus Oct 06 '14 at 14:25
  • Catching an OOM can often be perfectly reasonable and not a problem at all, when it's due to specific unsatisfiable allocation requests in a subtask. – Michael Borgwardt Oct 06 '14 at 14:32
  • @MichaelBorgwardt If you catch an OOME then you cannot create any new object in most cases. So it is difficult to do something useful in an object oriented language. Also all tips with allocating an emergency array can fail as you cannot influence the garbage collector. – Uwe Plonus Oct 06 '14 at 14:35
  • 1
    Usually you'd catch an OOME at a pretty high level, with many objects going out of scope and freeing up space. And if the error was caused by a single oversized allocation request, then there really is no problem at all. – Michael Borgwardt Oct 06 '14 at 15:05
  • 3
    @MichaelBorgwardt actually is quite the opposite, catching an OOME might make some sense at low level (say, I am requesting a 30 MB+ buffer to load a video file). In that case, you can expect and deal with the error easily (just replacing it with an exception/could not load control code). If you just capture the error at high level, the state of the system would be unknown (it is unknown which operations failed), and the only realistic option would be "resetting" all of the program states. – SJuan76 Oct 06 '14 at 16:26
  • @SJuan76: of course it depends on the structure of the application, but many (especially servers) have no global shared state, or keep it in a database with transaction semantics. – Michael Borgwardt Oct 06 '14 at 17:48
  • I can recall a major issue we had last year where a background thread in our web app (not tied to Tomcat's thread pool) listens to a queue of work to do and ran into a StackOverflowError from a few rare data conditions involving recursion. The urgency wasn't with the StackOverflowError. That was a minor edge case. The problem was nobody could figure out why this queue processing would sometimes stop until app servers are restarted. Eventually, when we realized the StackOverflowError was occuring and we had a thread pool of 3 and it was after the 3rd task that we failed, we figured it out. – Brandon Oct 07 '14 at 19:09
  • All of which could have been avoided if instead of catch (Exception e), we did catch (Throwable t). – Brandon Oct 07 '14 at 19:09
  • 1
    So I agree that catching Errors is often futile, but contrary to some of the absolute statements here, there are legitimate circumstances to catch Errors. – Brandon Oct 07 '14 at 19:11
  • @Brandon I know that such absolute statements are sometimes wrong. But in general you should really know what you're doing when catching Errors as it can be much worse than let the server dying and restart it... – Uwe Plonus Oct 08 '14 at 05:27
3

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.

Wyzard
  • 295
1

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.

jwenting
  • 9,783
0

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.

ddyer
  • 4,080