Java precisely defines an exception

In Java, we can catch exceptions of a certain type:

try{ // Code that does IO like download a file... }catch(IOException ioe){ ioe.printStackTrace(); // handle ioe }catch(SomeOtherException soe){ // handle soe } 

Now, for many reasons, exceptions, in this case, an IOException could be:

 java.io.IOException: Illegal character in path at index..... 

from a specific library or other type:

 java.io.IOException: Stream closed ... 

If something went wrong with Stream

Now, my question is: how to determine what an IOException occurred?

How can I distinguish between a Stream closed and an Illegal character in path at index... ?

Of course, I can just check the exception message line, but I do not think this is the best way, since the base library / implementation can change the message line.

EDIT:

e.getClass() in this case returns java.io.IOException for almost everything ...

I think the library throws its own IOException , throwing any original Exception .

+5
source share
3 answers

The fact that printStackTrace printed

 java.io.IOException: Stream closed ... // ^^^^^^^^^^^ 

and

 java.io.IOException: Illegal character in path at index..... // ^^^^^^^^^^^ 

means that Exception is of type IOException . There is no more specific subtype that you can use here.

In this case, there is no way. They decided to use the same type of Exception for both (or more) of these reasons. You cannot distinguish them from different catch statements. You will need to check their message.

If Exception has cause , you will need to see if there is a distinctive type and reconstruct it. If you're lucky, you can catch a more specific type of Exception .

+7
source

You can catch the exception differently since IOException is the top hierarchy of helper exceptions

From the documentation :

 java.io.IOException java.io.CharConversionException java.io.EOFException java.io.FileNotFoundException java.io.InterruptedIOException java.io.ObjectStreamException java.io.InvalidClassException java.io.InvalidObjectException java.io.NotActiveException java.io.NotSerializableException java.io.OptionalDataException java.io.StreamCorruptedException java.io.WriteAbortedException java.io.SyncFailedException java.io.UnsupportedEncodingException java.io.UTFDataFormatException java.io.UnsupportedEncodingException java.io.UTFDataFormatException 
+4
source

When a too general exception occurs in the library (as it seems you are working with an IOException here), you unfortunately do not have a lot of good options - essentially this is a bad design on the library part, Ideally you should file an error message or send a transfer request for the intruder library, but this may not be possible or possible.

However, all is not lost. First of all, it is possible that the library actually gives you more information than you think by including the main reason in the general IOException with Throwable.getCause() . This is a reliable way to provide more detailed debugging information when exposing a single Exception for normal processing. If this library follows this practice, you can do something like:

 catch(IOException e) { Throwable cause = e.getCause(); if(cause != null && cause instanceof URISyntaxException) { System.err.println("Bad URI"); } else { System.err.println("Other IOException"); } } 

Of course, the twist of what some Googling offers is a URISyntaxException in an IOException , it's not a terribly good design (an invalid URI, of course, not an I / O problem), so I won’t be surprised if the library just calls something like throw new IOException(e.getMessage()) and discards the original, that is, unfortunately, all you need is an exception message.

As you noted, parsing exception messages is not a good idea. Ideally, you should wrap this bad behavior in a helper method so that you can easily reorganize it after the library has been improved and determine if something unexpected happened and turned to it. Consider:

 public void doOperation(arguments) throws IOException, URISyntaxException { try { BadLibrary.doOperation(arguments); } catch(IOException e) { if(e.getMessage().startsWith("Illegal character")) { throw new URISyntaxException("Uknown", e.getMessage()); } else if(e.getMessage().startsWith("Stream closed")) { throw e; } else { // note we include the cause here throw new RuntimeException("Unexpected exception from BadLibrary", e); } } } 

With this compartmentalization, you only need to do this unpleasant check in one place, and you can be sure that you will find unexpected changes in the base library, instead of silently ignoring them.

+1
source

Source: https://habr.com/ru/post/1201267/


All Articles