Catching exceptions caused by temporary network errors - java

I have to download some URLs, and it can happen that during the operations some exception may occur, like java.net.NoRouteToHostException. I consider it a temporary error exception, as the download can succeed if you retry it after some time.
So, I'd like to catch all those exceptions related to temporary errors, and I've started with these: java.net.NoRouteToHostException, java.net.SocketException
Can you list other exceptions like these?

java.net.SocketException is the parent of java.net.NoRouteToHostException so you could maybe catch only the parent. The others childs of SocketException are BindException, ConnectException and PortUnreachableException. Maybe it's ok to catch only SocketExceptionin your case...

One pattern which is sometimes useful for dealing with transitory errors on retry-able operations is to define an error-callback interface and some classes that implement it; when an error occurs, let the callback object know, and let it decide whether an exception should be thrown or the action should be retried. Because the existing communications classes don't follow such a pattern, it may be necessary to catch their exceptions and turn them into callbacks.
Note that this approach allows much cleaner handling of many error-handling scenarios than would normal exception handling. Among other things, it makes it easy to set policies for how many retries may be attempted, how long they may take, etc. and also provides a means of skipping future retries if something like a "cancel" request is received.

As #reef has already said java.net.NoRouteToHostException exntends java.net.SocketException, so if you catch java.net.SocketException it is enough. But java.net.SocketException extends IOException and I think that this is what you really should to catch. All IO problems should throw this exception.

HttpRetryException is another. Maybe everything in java.net that does not extend SocketException?
One quick (and very dirty) way could be
try {
....
} catch(Exception e) {
if(e.getClass().getPackage().getName().equalsIgnoreCase("java.net")) {
retry();
}
}

Related

Is it okay to handle Runtime exceptions?

It's generally a good practice to not handle runtime exceptions.
I have this scenario :
/**boolean returns false if the method execution fails,
so that an error can be shown to user*/
boolean saveData()
{
try
{
//Some database calls that throw only Runtime exceptions
}
catch(Exception e)
{
//Log the exception and return false
return false;
}
return true;
}
So from the Servlet calling it will get a boolean value. If it's false, we show a message 'Save Not sucessful'. Is this okay or is there a better way of doing it ?
Is it okay to handle Runtime exceptions?
As long as you can do something intelligent at that point, yes. This 'never catch run-time exceptions' is pure nonsense. You'll probably want to log them and do other things, as well.
It's generally a good practice to not handle runtime exceptions.
This sentence implies a false premise: the question is not whether, but when to catch runtime exceptions.
At some point in your code you should definitely have a "catch-all" exception handler. This point is called the exception barrier, and it is high enough in the call stack to encompass a complete unit of work (basically, the scope of one database transaction).
This should be your governing principle:
if an exception must cause the current unit of work to be aborted (rolled back), then do not catch that exception until the exception barrier;
if an exception is of local character only, and its appearance only means taking a different route to the handling of the request, then do catch and handle it early.
Note that the above doesn't use the fruitless checked/unchecked distinction. Most modern frameworks completely avoid checked exceptions and go out of their way to shield the programmer from such exceptions being thrown from lower-level code.
In practice, more than 90% of all exceptions are of the first, aborting kind. This is what is meant by the term "unrecoverable"—it means you can't continue what you are doing right now, but the server can stay up and process all other requests. I see many people confusing this with "the JVM is about to die", but exceptions which have that meaning are exceedingly rare and usually there is no special handling code for them.
Lastly, note that the "catch-all" handler should catch not only RuntimeExceptions but also Errors because you want every exception logged the same way. If you let an exception escape your application code, there is no knowing what behavior it will cause. Note that there are some common errors, like StackOverflow and OutOfMemory, which can in principle cause unrecoverable damage and therefore rightfully belong to the Error hierarchy, yet in most real-life cases do no damage beyond aborting the current request. You definitely do not want to shut down your service at the first sight of such an error.
No, catching a general Exception will mask any other problems you don't want to catch. Better catching specific exceptions making it harder for unexpected ones to go missing.
I guess your question has two aspects: 1) Handling RuntimeExceptionas the heading suggested and 2) handling generic Exception these are two different things.
The Javadoc of RuntimeExcepton list a bunch of its subclasses (NullPointerException..etc). If you look carefully, these are nothing but the programming errors and instead of handling them in catch block, should be corrected the the code itself so that they do not occur.
Handling generic Exception is generally referred as a poor practice and rightly so because it hides the specific exceptions which might need different handling.
But in case similar to yours, if there is a Servlet giving a call to method there has to be a graceful way to tell the user that there was some problem with the application while processing the request instead if showing the stacktrace.
So what you are doing could be one way of handling and as a good practice keep track of errors/exceptions in the log and correct any RuntimeExceptions
boolean returns false if the method execution fails,
so that an error can be shown to user
This is a clear reason for the method to throw an exception. It is why the exception mechanism exists in the first place. Best practice is to use exceptions for these types of circumstances, not boolean signals.
Anytime you follow this kind of pattern, you suffer in several ways
The caller cannot be sure what really happened. Was there a communication failure? Was the data corrupted? There is no way to tell when you return a simple "FAILED" signal.
Because the caller cannot know what happened, you take away options for the caller. Maybe the caller could do something in certain error cases.
You increase the potential for data errors. Again, since the caller cannot know why it failed, the caller may make assumptions about why it failed and continue in cases when the entire program should halt. If the program continues, it may decide to process invalid data when it really should stop.
I highly recommend reading the sections on exception handling in Effective Java. Basically, if you can't do anything meaningful with an Exception in your method, you should allow it to pass up the stack. In the worst case scenario, the API you reference throws a generic checked exception, giving you one of three choices (EDIT: Changed to void return type because the boolean return type no longer has any meaning -- you either succeed or throw an exception)
-Create your own.
// "MyFatalException" would be a checked Exception
public void saveData() throws MyFatalException{
try{
// ... do stuff that throws Exception
}catch(Exception e){
throw new MyFatalException("Unable to save Data due to a general exception"+
" thrown by foo.bar()", e);
}
}
-Throw an existing type (my preference is for subclasses of RuntimeException)
public void saveData() throws IllegalStateException{
try{
// ... do stuff that throws Exception
}catch(Exception e){
throw new IllegalStateException("Unable to save Data due to a general exception"+
" thrown by foo.bar()", e);
}
-Declare to throw a generic Exception and let it pass up (I do NOT recommend this, but you'll see many developers who do this)
public void saveData() throws Exception{
// no try/catch needed. Just make the call
}
The general concept is that frameworks or APIs would throw a RuntimeException only in situations when the error is not recoverable in code. e.g: your Db is down, or your server socket is down and things like that.
Though its not bad to catch such exceptions but whats actually thoughtful is what do you intend to do after catching them. e.g: people prefer to catch DB level connection problems and errors which are runtime exception subclasses and show error pages on their websites. Checked exceptions are usually for code level situational cases and catching them and handling is what code is expected to do.
In case you try something like this, since you don't want your users to error page you can do this, provided you caught all other exceptions before this.
boolean saveData()
{
try
{
//Some database calls that throw only Runtime exceptions
}catch(db_Connectivity_Exception e){
//exception like credentials invalid
}catch(db_table_Exception e){
//table desc. changed
}
catch(Exception e)
{
//Log the exception and return false
//Since you are going to log your error I hope is not harmfu
return false;
}
return true;
}
Still this is not best practice

Java Domain Exceptions

I had written a restful web service. The contract of the restful web service is to receive parameters, communicate to a external service via SSL and respond back to the client. There are no issues in the service contract and the service. The service design was good and all the checked exceptions have been caught in the catch block but after a few service testing, then it seemed that the unchecked exceptions are not handled properly. Is there are any way to encapsulate these unchecked exception using domain exceptions. To be simple, how to handle or anticipate the unchecked exceptions.
In the specific case of a restful web service, the framework has a 'catch-all' handler that does something you don't like. So, contra some other answers here, there's nothing evil about adding more or different handling. The framework's handler is certainly not cleaning up for you, so you can only make things better by cleaning up for yourself. Thus, you have two choices.
you can add an exception mapper to your list of providers, as per the JAX-RS standard.
You can wrap your code in a try/catch of Throwable, and then construct a Response that appeals to you in the catch handler.
Without knowing what toolkit you are using for JAX-RS I can't be more detailed about (1).
You should always have a single place in your code where you handle all exceptions and what you describe sounds like you have a mess of handling code all around, wherever a method is called that declares checked exceptions. Use this code in lower-level code that encounters checked exceptions:
try {
...
catch (RuntimeException e) { throw e;}
catch (Exception e) { throw new RuntimeException(e); }
And at the exception barrier (that central place mentioned) use
try {
...
catch (Throwable t) { // logging, returning error response, whatever
}
finally { // global resource cleanup
}
Doing more than this is required only in special cases, which you will find are not very common in the code base, and that is when your lower-level methods acquire resources additional to the resources already acquired for each request. An example could be file I/O. In such cases it is of course mandatory to use a try-finally to take care of that extra resource, but you still must not catch and swallow exceptions: the main exception barrier still needs to know there was a problem and do its cleanup.
RuntimeExceptions should indicate coding errors, so ideally you should fix the bugs rather than trying to handle them. Unfortunately some library developers misuse RTEs for non-bugs and force you to catch them. You can wrap a RuntimeException in an Exception.
....
catch (RuntimeException e) {
throw new MyCheckedException("Failed to...", e);
}
EDIT: It seems it's a controversial view these days. I know that bad checked exceptions can be a pain. But good use of checked exceptions helps clients and implementers to understand the contract. Using RuntimeExceptions for non-bugs may make it easier to work with an API in the 'happy case', when you don't care about exceptions, but much harder to know what to expect of the 'sad case' when you do. It also makes it harder for implementers of interfaces to know what's expected of them - which RuntimeExceptions they are or aren't allowed to throw etc.

Why is the Catch(Exception) almost always a bad Idea?

Why is the catch(Exception) almost always a bad Idea?
Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. 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.
Short story: it's called bug masking. If you have a piece of code which is not working well and throwing exceptions (or you pass malformed input to that piece of code) and you just blind your eyes by catching all possible exceptions, you will actually never uncover the bug and fix it.
You should only catch exceptions if you can properly handle them. As you cannot properly handle all possible exceptions you should not catch them :-)
It depends on what you need. If you need to handle different types of exceptions in different ways then you should use multiple catch blocks and catch as much specific exceptions as you can.
But sometimes you may need to handle all exceptions in the same way. In such cases catch(Exception) may be ok. For example:
try
{
DoSomething();
}
catch (Exception e)
{
LogError(e);
ShowErrorMessage(e); // Show "unexpected error ocurred" error message for user.
}
Because you don't really know why an exception happened, and several exceptions require very special car to be handled correctly (if possible at all), such as a OutOfMemoryException and similar low-level system exceptions.
Therefore, you should only catch exceptions:
which you know exactly how to deal with it (e.g. FileNotFoundException or so)
when you will re-raise them afterwards (for instance to perform post-fail cleanup)
when you need to transport the exception to another thread
I find two acceptable uses of catch(Exception):
At the top level of the application (just before returning to the user). That way you can provide an adequate message.
Using it to mask low-level exceptions as business ones.
The first case is self-explanatory, but let me develop the second:
Doing:
try {
// xxxx
} catch(Exception e) {
logger.error("Error XXX",e)
}
is bug masking like #dimitarvp said.
But the below is different:
try {
// xxxx
} catch(Exception e) {
throw new BusinessException("Error doing operation XXX",e)
}
This way you aren't ignoring bugs and hiding them under the carpet. You are providing a high-level exception with a more explanatory message to higher application layers.
It's also always important to manage exceptions at the correct layer. If you escalate a low-level exception to a high business layer, it's practically impossible for the higher layer to manage it well.
In that case, I prefer to mask the low level exceptions with a business one that provides a better context and message and that also has the original exception to be able to go into the details.
Even so, if you can catch more concrete exceptions and provide better treatment for them you must do it.
If in a block of code you can get an SQLException and a NetworkException you must catch them and provide adequate messages and treatment for each of them.
But if at the end of the try/catch block you have an Exception mapping it to a BusinessException it's ok for me.
In fact, I find it adequate when higher service layers only throw business exceptions (with details inside).
Besides what yet answered by #anthares:
Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. 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.
This may be java specific:
Sometimes you will need to call methods that throw checked exceptions. If this is in your EJB / business logic layer you have 2 choices - catch them or re-throw them.
Catching specific exception classes means you will need to re-analyze your actions for which exceptions can be thrown when you look to see how this code handles exceptions. You will often get into a "what if..." situation and it can be a lot of effort just working out if exceptions are handled correctly.
Re-throwing means that code calling your EJBs will be littered with catching code that will typically not mean anything to the calling class. n.b. throwing checked exceptions from EJB methods will mean that you are responsible for manually rolling back any transactions.
But sometimes it is OK! Like if you have a piece of code that does something 'extra', which you really don't care about, and you don't want it to blow up your application. For example, I worked on a large application recently where our business partners wanted a certain daily transaction to be summarized in a new log file. They explained that the log wasn't all that important to them, and that it did not qualify as a requirement. It was just something extra that would help them make sense of the data being processed. They did not need it, because they could get the information elsewhere. So that is a rare case where it is perfectly fine to catch and swallow exceptions.
I also worked at a company where all Throwables were caught, and then rethrown inside a custom RuntimeException. I would not recommend this approach, but just pointing out that it is done.
Isn't it another valid scenario to ensure that a thread keeps alive catching exception inside it?
Thread shouldRunWhenApplicationRuns = new Thread() {
#Override
public void run() {
try {
// do something that should never end
} catch (Exception ex) {
// log it
}
};
shouldRunWhenApplicationRuns.start();
Sonar has also a good Explanation, why this is not a good idea, and how it can be prevented:
https://rules.sonarsource.com/java/RSPEC-2221
Catching Exception seems like an efficient way to handle multiple possible exceptions. Unfortunately, it traps all exception types, both checked and runtime exceptions, thereby casting too broad a net. Indeed, was it really the intention of developers to also catch runtime exceptions? To prevent any misunderstanding, if both checked and runtime exceptions are really expected to be caught, they should be explicitly listed in the catch clause.

Should I catch exceptions thrown when closing java.sql.Connection

Connection.close() may throw SqlException, but I have always assumed that it is safe to ignore any such exceptions (and I have never seen code that does not ignore them).
Normally I would write:
try{
connection.close();
}catch(Exception e) {}
Or
try{
connection.close();
}catch(Exception e) {
logger.log(e.getMessage(), e);
}
The question is:
Is it bad practice (and has anyone had problems when ignoring such exceptions).
When Connection.close() does throw any exception.
If it is bad how should I handle the exception.
Comment:
I know that discarding exceptions is evil, but I'm reffering only to exceptions thrown when closing a connection (and as I've seen this is fairly common in this case).
Does anyone know when Connection.close() may throw anything?
Actually, what you're doing is (almost) best practice :-) here's what I saw in Spring's JdbcUtils.java. So, you might want to add
another Catch block.
/**
* Close the given ResultSet and ignore any thrown exception.
* This is useful for typical finally blocks in manual code.
* #param resultSet the ResultSet to close
* #see javax.resource.cci.ResultSet#close()
*/
private void closeResultSet(ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
}
catch (SQLException ex) {
logger.debug("Could not close ResultSet", ex);
}
catch (Throwable ex) {
// We don't trust the driver: It might throw RuntimeException or Error.
logger.debug("Unexpected exception on closing ResultSet", ex);
}
}
}
In general, I've had days wasted by people throwing away exceptions like that.
I recommend following a few basic rules with exceptions:
If you are ABSOLUTELY SURE you will NEVER cause a problem with a checked exception, catch JUST that exception and comment exactly why you don't need to handle it. (Sleep throws an InterruptedException that can always be ignored unless you actually are interested in it, but honestly this is the only case I usually ignore--even at that, if you never get it, what's the cost of logging it?)
If you are not sure, but you may get it occasionally, catch and log a stack trace just so that if it is causing a problem, it can be found. Again, catch only the exception you need to.
If you don't see any way the checked exception can be thrown, catch it and re-throw it as an unchecked exception.
If you know exactly what is causing the exception, catch it and log exactly why, you don't really need a stack trace in this case if you are very clear as to what's causing it (and you might mention the class that's logging it if you're not already using log4j or something.
It sounds like your problem would fall into the last category, and for this kind of a catch, never do what you wrote (Exception e), always do the specific exception just in case some unchecked exception is thrown (bad parameters, null pointer, ...)
Update: The main problem here is that Checked Exceptions are ungood. The only highly used language they exist in is Java. They are neat in theory, but in action they cause this behavior of catch and hide that you don't get with unchecked exceptions.
A lot of people have commented on the fact that I said that hiding them is okay sometimes. To be specific, the one case I can think of is:
try {
Thread.sleep(1000);
catch (InterruptedException e) {
// I really don't care if this sleep is interrupted!
}
I suppose the main reason I feel this use is okay is because this use of InterruptedException is an abuse of the checked exception pattern in the first place, it's communicating the result of a sleep more than indicating an exception condition.
It would have made much more sense to have:
boolean interrupted=Thread.sleep(1000);
But they were very proud of their new checked exception pattern when they first created Java (understandably so, it's really neat in concept--only fails in practice)
I can't imagine another case where this is acceptable, so perhaps I should have listed this as the single case where it might be valid to ignore an exception.
At the very minimum, always always always log exceptions that you are catching and not acting on.
Silently caught exceptions that are swallowed without the tiniest peep are the worst.
I personally like your second idea of at least logging the error. Because you're catching Exception, it's theoretically possible to catch something other than a SQL Exception. I'm not sure what could happen or how rare (like out of memory exceptions, etc) but supressing all errors doesn't seem right to me.
If you want to suppress errors, I would do it only to very specific ones you know should be handled that way.
Hypothecial situation: what if your sql had an open transaction, and closing the connection caused an exceptino because of that, would you want to suppress that error? Even suppressing SQLExceptions might be a little dangerous.
You have to handle the exception. It is not a bad practice. Imagine you lost the network just before closing the dabatase connection. It will probably throw the exception.
Is it rare ? Yes. I suppose that's what they are called exceptions and that is not a reason to ignore it. Remember that if it could fail, it will fail.
You should also think about whether it is possible to have a null connection at this point (it would cause a NullPointerException) or not.
if (connection != null) {
try {
connection.close();
} catch (SQLException sqle) {
logger.log(e.getMessage(), e);
}
}
In an ideal world, you should never do nothing on an exception, of course, in an ideal world, you would never get an exception either 8-)
So, you have to examine the impacts of the various options.
Log only: Database operations are all finished, nothing left to do but clean up the resources. If an exception occurs at this point, it most likely has no impact on the work performed, so logging the error should suffice. Of course, if an error occurs during logging, then you basically have to handle failed database operation that didn't actually fail.
Empty handler: Database operations are all finished, nothing left to do but clean up the resources. If an exception occurs at this point, it most likely has no impact on the work performed, so the method returns successfully. The next database access may run into the same problem, but it should occur at the start of a transaction, where it will rightly fail and then get handled appropriately. If the problem has fixed itself, then there will be no indication that anything ever went wrong.
It is a pretty typical scenario to put a close() operation(s) in a finally block to ensure that cleanup occurs, since we don't want any other failures to inhibit the resource cleanup. If no error has occurred, then your method should not fail when its operation has successfully completed. In this case, empty exception handling is quite normal.
Of course opinions will vary.
You could also throw a RuntimeException:
try {
connection.close();
} catch(Exception e) {
throw new RuntimeException(e);
}
You won't have to change your method signature and will be able to use the Exception.getCause method later on to find the cause of the problem.
Note that Apache Commons DButils provides a closeQuietly() method, that you can use to avoid cluttering your code with 'redundant' catches. Note I'm not advocating swallowing exceptions, but for this close() scenario I think it's generally acceptable.
From my experience ignoring an exception is never a good idea.
Believe me, the production support engineers and analysts will thank you a tonne if you logged the exception.
Also, if you are using the right Logging framework, there would be zero or minimal performance impact of the exception.
if this is an "error that never happens" case then I will just rethrow an Exception and hope no one catches it.
if this is any other case I will probably log it
If you can handle it, then do so (and log it if it was unexpected). If you cannot handle it, then rethrow it properly so some code above can handle it.
Silently swallowing exceptions is leaving out crucial information for the person to fix the code.
Its a better practice to handle the exception at the time of closing the connection to the database. Because, at later some point of time in your code, if you are trying to access the statement or resultset objects then it will automatically raise an exception. So, Better to handle the exception.

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

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?
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.
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.
A lot of the other answers are looking at things too narrowly.
As they say, if you are writing application code, you should not catch Throwable. You can't do anything about it, so allowing the surrounding system (JVM or framework) to handle these issues is best.
However, if you are writing "system code", like a framework or other low-level code then you may very well want to catch Throwable. The reason is to attempt to report the exception, perhaps in a log file. In some cases your logging will fail, but in most cases it will succeed and you will have the information you need to resolve the issue. Once you have made your logging attempt you should then either rethrow, kill the current thread, or exit the entire JVM.
Usually Errors are problems you cannot possibly recover from, like OutOfMemoryError. There's nothing to do by catching them, so you should usually let them escape, and bring down the virtual machine.
I'll go a slightly different route from others.
There are many cases where you would want to catch Throwable (mainly to log/report that something evil happened).
However, you need to be careful and rethrow anything that you cannot deal with.
This is especially true of ThreadDeath.
If you ever catch Throwable, be sure to do the following:
try {
...
} catch (SomeExceptionYouCanDoSomethingWith e) {
// handle it
} catch (ThreadDeath t) {
throw t;
} catch (Throwable t) {
// log & rethrow
}
There's at least one case when I think you may have to catch a throwable or a generic exception - if you're running a separate thread to perform a task, you may want to know if the "run" method of the thread has catched some exception or not. In that case, you probably will do something like this:
public void run() {
try {
...
}
catch(Throwable t) {
threadCompletionError = t;
}
}
I am really not sure if it's the best approach, but it works. And I was having a "ClassNotFound" error being raised by the JVM, and it's an error and not an exception. If I let the exception be thrown, I am not sure how to catch it in the calling thread (probably there's a method but I don't know about it - yet).
As for the ThreadDeath method, don't call the "Thread.stop()" method. Call Thread.interrupt and have your thread to check if it was interrupted by someone.
This post won't make the "checked exceptions are bad" people happy. However, what I am basing my answer on is how Java exceptions are intended to be used as defined by the people that created the language.
Quick reference chart:
Throwable - never catch this
Error - indicates a VM error - never catch this
RuntimeException - indicated a programmer error - never catch this
Exception - never catch this
The reason you should not catch Exception is that it catches all of the subclasses, including RuntimeException.
The reason you should not catch Throwable is that it catches all of the subclasses, including Error and Exception.
There are exceptions (no pun intended) to the above "rules":
Code you are working with (from a 3rd party) throws Throwable or Exception
You are running untrusted code that could cause your program to crash if it thew an exception.
For the second one usually it is enough to wrap main, event handling code, and threads with the catch to Throwable and then check the actual type of the exception and deal with it as appropriate.
Do NOT ever catch Throwable or Error and you should generally not simply catch a generic Exception either. Errors are generally things that most reasonable programs cannot possibly recover from. If you know what is going on, you might be able to recover from one specific error, but in that case, you should catch only that one particular error and not all errors in general.
A good reason not to catch Error is because of ThreadDeath. ThreadDeath is a fairly normal occurrence that can theoretically be thrown from anywhere (other processes like the JVM itself can generate it), and the whole point of it is to kill your thread. ThreadDeath is explicitly an Error rather than an Exception because too many people catch all Exceptions. If you ever were to catch ThreadDeath, you must rethrow it so that your thread actually dies.
If you have control over the source, it should probably be restructured to throw an Exception rather than an Error. If you don't, you should probably call to the vendor and complain. Errors should be reserved for only things that are terminal with no possible way to recover from them.
Normally when programming, you should only catch a specific exception (such as IOException). In a lot of programs you can see a very toplevel
try {
...
} catch(Exception e) {
...
}
That catches all errors which could be recoverable and all those which indicate a bug in your code, e.g. InvalidArgumentException, NullPointerException. You can then automatically send an eMail, display a message box or whatever you like, since the JavaVM itself is still working fine.
Everything derived from Error is something very bad, you can't do anything against. The question is, if it makes sense to catch a OutOfMemoryError or a VirtualMachineError. (It is a error in the JavaVM itself, probably you can't even display a message box or send an eMail then)
You should probably not a class derived from Error, you should derive from Exception or RuntimeException.
I know it might be counter-intuitive, but just because you can catch all sorts of Exceptions and Throwables and Errors does not mean you should.
Over-aggressive catching of java.lang.Exception can lead to some serious bugs in applications - because unexpected Exceptions never bubble up, are never caught during development/testing, etc.
Best practice: only catch
Exceptions that you can handle
Exceptions that are necessary to catch
In general it would be reasonable to try to catch Errors if only so that can be properly reported.
However, I believe there are cases when it would be appropriate to catch an Error and not report it. I'm referring to UnsatisfiedLinkError. In JAI the library uses some native libraries to implement most of the operators for performance reasons, however if the library fails to load (doesnt exist, wrong format, unsupported platform) the library will still function because it will fall back into a java only mode.
Slightly off topic, but you may also want to look at this very good article about exceptions.
Why not catch them all? Then log them, at least you know you have an error. So better catch Throwable/s than Exception/s only.
There is no point in catching Error.
Errors are used to indicate something went really wrong in your application and it should be restarted.
For instance one common error is
java.lang.OutOfMemoryError
There is NOTHING you can do when that happens. Is already too late, the JVM has exhausted all its options to get more memory but it is impossible.
See this other answer to understand more about the three kinds of exceptions.

Categories

Resources