views:

68850

answers:

11

In what situations should one catch java.lang.Error on an application?

+3  A: 

Almost never. Errors are designed to be issues that applications generally can't do anything about. The only exception might be to handle the presentation of the error but even that might not go as planned depending on the error.

nicerobot
+22  A: 

Never. You can never be sure that the application is able to execute the next line of code. If you get an OutOfMemoryError, you have no guarantee that you will be able to anything. Catch RuntimeException and checked Exceptions, but never Errors.

http://pmd.sourceforge.net/rules/strictexception.html

tronda
I don't think this can be stressed enough. My all-time favorite WTF was when I noticed a co-worker catching Throwable, but catching Error is nearly as bad.
Bill the Lizard
Never say never. we have testing code that does an "assert false;" then catches the AssertionError to makes sure that the -ea flag is set.Other than that...yeah, probably never ;-)
Outlaw Programmer
How about a server application that hands requests off to worker threads. Might it not make sense to catch Throwable on the worker thread to trap any errors, and at least try and log what's gone wrong?
Leigh
Never...except when you absolutely need to. Never is a strong word and there are always exceptions to the rules. If you are building a framework, it's not that unlikely that you will have to catch and handle certain errors, even if it is just to log.
Robin
+4  A: 

And there are a couple of other cases where if you catch an Error, you have to rethrow it. For example ThreadDeath should never be caught, it can cause big problem is you catch it in a contained environment (eg. an application server) :

An application should catch instances of this class only if it must clean up after being terminated asynchronously. If ThreadDeath is caught by a method, it is important that it be rethrown so that the thread actually dies.

Guillaume
Which is actually a non-issue because you simply do *not* catch `Error`s.
Bombe
+15  A: 

Generally, never. However, sometimes you need to catch specific Errors.

If you're writing framework-ish code (loading 3rd party classes), it might be wise to catch LinkageErrors (no class def found, unsatisfied link, incompatible class change). I've also seen some stupid 3rd-party code throwing sublcasses of Errors, so you'll have to handle these either.

By the way, I'm not sure it isn't possible to recover from OutOfMemory.

Yoni Roit
That I had to do exactly to load DLLs, that would fail if they were not correctly configured. Not a fatal error in case of this application.
Mario Ortegón
+4  A: 

Very rarely.

I'd say only at the top level of a thread in order to ATTEMPT to issue a message with the reason for a thread dying.

If you are in a framework that does this sort of thing for you, leave it to the framework.

Darron
A: 

An Error usually shouldn't be caught, as it indicates an abnormal condition that should never occur.

From the Java API Specification for the Error class:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. [...]

A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur.

As the specification mentions, an Error is only thrown in circumstances that are Chances are, when an Error occurs, there is very little the application can do, and in some circumstances, the Java Virtual Machine itself may be in an unstable state (such as VirtualMachineError)

Although an Error is a subclass of Throwable which means that it can be caught by a try-catch clause, but it probably isn't really needed, as the application will be in an abnormal state when an Error is thrown by the JVM.

There's also a short section on this topic in Section 11.5 The Exception Hierarchy of the Java Language Specification, 2nd Edition.

coobird
+2  A: 

Very, very rarely.

I did it only for one very very specific known cases. For example, java.lang.UnsatisfiedLinkError could be throw if two independence ClassLoader load same DLL. (I agree that I should move the JAR to a shared classloader)

But most common case is that you needed logging in order to know what happened when user come to complain. You want a message or a popup to user, rather then silently dead.

Even programmer in C/C++, they pop an error and tell something people don't understand before it exit (e.g. memory failure).

Dennis Cheung
+2  A: 

If you are crazy enough to be creating a new unit test framework, your test runner will probably need to catch java.lang.AssertionError thrown by any test cases.

Otherwise, see other answers.

noahz
+2  A: 

Generally you should catch it ever and write it to a log or display it to the user. I am working in the support an I see it daily that programmers does not know what go on in your program.

If you have daemon thread then you must prevent that it terminated. In the other case your application will work correctly.

You should catch it only on the top.

If you see the list of errors then you see that the most can be handled. For example a ZipError occur on reading corrupt zip files.

The most errors are OutOfMemoryError and NoClassDefFoundError. Both are in most cases runtime problems.

for example: int length = Integer.parseInt(xyz); byte[] buffer = new byte[length];

can produce an OutOfMemoryError but it is a runtime problem and not the cause to terminate your program.

The NoClassDefFoundError occur mostly if a library is not present or if you work with another Java version. If it is an optional part of your program then you should not terminate your program.

I can write many more samples why it is a godd idea to catch Throwable on top and produce an helpful error output.

Horcrux7
+2  A: 

In multithreaded environment, you most often want to catch it! When you catch it, log it, and terminate whole application! If you don't do that, some thread that might be doing some crucial part would be dead, and rest of the application will think that everything is normal. Out of that, many unwanted situations can happen. One smallest problem is that you wouldn't be able to easily find root of the problem, if other threads start throwing some exceptions because of one thread not working.

For example, usually loop should be:

try {
   while (shouldRun()) {
       doSomething();
   }
}
catch (Throwable t) {
   log(t);
   stop();
   System.exit(1);
}

Even in some cases, you would want to handle different Errors differently, for example, on OutOfMemoryError you would be able to close application regularly (even maybe free some memory, and continue), on some others, there is not much you can do.

Sarmun
A: 

So if we catch Throwable...do we need a finally clause at all.. Handle all in throwable (what you wanted to do in finally)

Neal