Hobbyist
Hobbyist

Reputation: 16202

Handling different exceptions of the same type in Java?

When handling errors in Java it's common to see the superclasses being the errors that are caugh, such as

Exception, IOException, SocketException, etc.

However how do you go about finding the nitty-gritty details on the exception? How do you single a certain exception type out from the others. For instance, I'm currently working on a small project using Netty.io which throws an IOException for every type of read/write error you can name. This makes sense, because ultimately this is input/output errors, but how would I handle them individually.

Example exceptions:

java.io.IOException: An existing connection was forcibly closed by the remote host
java.io.IOException: Connection reset by peer
java.io.IOException: Stream closed

The list just continues to go on, but how would you go about handling these seperately, one approach that I've found while looking around and seems really nasty is the following.

try { 
    // ...
} catch (IOException e) { 
    if(e.getMessage().contains("An existing connection was forcibly closed by the remote host")) {
        // Handle error
    } else //...
}

This seems very tedious and there's bound to be a better way to do this, a correct way if you will. I've looked through quite a bit of error handling writeups over the last few hours and they all only talk about the big boys that are used commonly. IOException, Exception, SocketException, NullPointerException, and FileNotFoundException. Where I believe SocketException and FileNotFoundException would be directly related to the IOException, more than likely a subclass, correct me if I'm wrong.

Anyway, what's the proper way to go about handling these exceptions and how do you figure out exactly what kind of exception you need to be handling? All I can really do is handle IOException until something more precise comes up, but when developing applications it's always good to be able to handle each error uniquely.

Upvotes: 6

Views: 2662

Answers (3)

user207421
user207421

Reputation: 310936

In most of these cases the message is irrelevant from the point of view of your code. It's just something to be shown to the user, or logged. The only salient fact is that the connection is broken, for whatever reason, and there aren't different code paths you can use depending on which message it was.

The only one that's different is 'socket closed', which indicates a coding bug.

EDIT Regarding your comments below:

  • Any IOException other than SocketTimeoutException on a socket is fatal to the connection.
  • Invalid packets don't cause IOException: that's an application-layer problem that throws application-layer exceptions, or subclasses of IOException: e.g., java.io.StreamCorruptedException.
  • There is no such thing as IOException: connection closed by remote host. If the peer closes the connection, that causes an end-of-stream condition, which manifests itself as either read() returning -1, readLine() returning null, or readXXX() throwing EOFException for any other X.

Upvotes: 2

afi
afi

Reputation: 578

The documentation (http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html) contains a long list of direct subclasses. You might want to look through them and check which ones you want to treat differently. Once you know that, you can use multiple catch-blocks, first the subclasses, then the most general IOException:

catch(SSLException se) {
  // do something
}
catch(HttpRetryException he) {
  // do something else
}
catch(IOException ioe) {
  // nop
}

Upvotes: 1

edenzik
edenzik

Reputation: 146

I would suggest catching the exceptions in order, from most specific to least - such that you will notice a circuit break pattern when the exception you are looking for is reached. This is the best I can come up with:

try {
   /// Something that can result in IOException or a SocketException
catch (IOException e){
   //Do something specific
}catch (SocketExcpetion e){

}catch (Exception e) { //or some superclass of the above exceptions
 ///
}

Don't forget that you can also catch multiple exceptions of different types using the | command: catch (IOException|SocketException|

Upvotes: 1

Related Questions