How to handle multiple exceptions in a java method? - java

I've read It isn't a best practice to handle multiple Exceptions like this:
public void myMethod() throws ExceptionA, ExceptionB, ExceptionC {
//more code here
}
And then to call myMethod():
try {
myObject.myMethod();
} catch(Exception e) {
//More code here
}
Despite Exception is the parent class of all the other exceptions, it is consider a bad practice. But, in my application I'm using java SE 6 and I need to:
Do File operations that can imply a FileNotFOundException and IOException
Marshal objects (in order to create XML files) JAXBException
Create a pdf file (using pdfbox library) COSVisitorException
Send an email using JavaMail, MessagingException
The easiest way is to add a throws statement in method declaration, but what could be the proper way to write the client method?
Is it OK to add 6 or 7 catch blocks to handle all the possible exceptions?

Generally speaking (for Java 6 and below), you should handle each exception individually...
try {
myObject.myMethod();
} catch (ExceptionA e) {
// Condition for A
} catch (ExceptionB e) {
// Condition for B
} catch (ExceptionC e) {
// Condition for C
}
This allows you to handle each exception differently based on what it is, but also means you are only handling those exceptions reported to be thrown by the method
In Java 7+ you can make use of "multi-catch" or "combined catch" (we can't find an "official" term)
try {
myObject.myMethod();
} catch (ExceptionA | ExceptionB | ExceptionC e) {
// Condition for A and B and C
}
But even then, you should be focusing exceptions into "common" use groups
try {
myObject.myMethod();
} catch (ExceptionA | ExceptionB e) {
// Condition for A and B
} catch (ExceptionC e) {
// Condition for C
}
Another option, if you control how the exceptions are defined, is to extend from a common base exception, a good example of this is the FileNotFoundException which extends from the IOException, which is thrown by FileReader and FileInputStream (as examples), this means you can handle the FileNotFoundException as a common IOException should you wish...
FileReader fr = null;
try {
fr = new FileReader(new File(...));
// Read from reader...
} catch (IOException exp) {
// Common catch block
} finally {
// Best attempt to close
try {
fr.close();
} catch (Exception exp) {
}
}
Or you could handle the FileNotFoundException as it's own condition...
FileReader fr = null;
try {
fr = new FileReader(new File(...));
// Read from reader...
} catch (FileNotFoundException exp) {
// File not found condition
} catch (IOException exp) {
// Other IO condition
} finally {
// Best attempt to close
try {
if (fr != null) {
fr.close();
}
} catch (Exception exp) {
}
}
This allows you to either group "like" exceptions together, but also provides you with the control to define more fine grained conditions should you need to...
Beware though, we the above example, if I put the IOException first, the FileNotFoundException would never be handled, when doing this, make sure that you use the lowest/tightest/finest exceptions first, as they are processed sequentially in the order you have listed
Another option (which I'm not keen on, but have seen) might be to catch a "common" ancestor and then compare the actual type, which would allow you to provide common handlers for some sub-type of the exception.
} catch (IOException exp) {
if (exp instanceof FileNotFound || exp instanceof FileSystemException) {
// Common handling
} else {
// Generic handling
}
}
This might be helpful in situations where the method only throws the ancestor type (ie IOException), but you need to provide a more fine grained resolution
But, again, I would be focused on only handling the expected "common" exceptions declared as been thrown, don't be tempered to catch Throwable for example

Related

Multiple Handling Exceptions in java

I need to handle a particular exception and rest of all other exception which should gives us the same logging information but the level of logging should be different ( Former should be going to log.warn and the rest of them should be going to log.error)
try {
}
catch (someexception e) {
log.warn("some message")
-----some code----
}
catch(AllotherExceptions e) {
log.error("same message as above")
-----same code as above----
}
This needs to minimalized as the message is the same but need to make the rest of the code as a common code rather than writing it couple of times
You have several ways to do so. You can, as shown in previous answers, make successive catch statements like this :
try {
// Code that potentially throws multiple exceptions
}
catch (IOException ex) {
// Manage this particular exception case
}
catch (Exception ex) {
// Manage remaining exceptions
}
This way you'll be able to manage particular cases and define a point where all the exceptions related to the following actions will be managed. By putting this try statement early in your process (main loop, heavy service call...), you'll manage many exceptions but you'll not be able to manage specific cases since you won't know which particular actions threw them. By wrapping little specific actions (accessing files, requesting...), you'll be able to make very specific management of these exceptions.
As pointed in the answers, with Java >= 7 this syntax will work :
try {
// Code that potentially throws multiple exceptions
}
catch (IOException|SQLException ex) {
// Manage these particular exceptions
}
catch (Exception ex) {
// Manage remaining exceptions
}
This way is to be used when you need to manage different exceptions the exact same way. It's particularly helpful when a single action would throw different exceptions (ie accessing files) but you only want want to manage a few specific error cases in particular and not worrying about everything that can be thrown.
You can use multiple catch blocks to accomplish this, and catch Exception, the base class for all checked exceptions, last. For example:
try {
// Your code here.
} catch (SpecificException e) {
log.warn("Warning!", e);
} catch (AnotherSpecificException e) {
log.warn("Another warning!", e);
} catch (Exception e) {
log.error("Error!", e)
}
Just add several catch sections and finish with a catch all.
try {
// Some code
}
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (Exception ex) {
logger.log(ex);
throw ex;
}
Read more here: Documentation
try{
//try something
} catch (SomeTypeException e){
//things
} catch (AnotherException e){
//AnotherThings
}
The following example, which is valid in Java SE 7 and later, eliminates the duplicated code:
try{
}
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
since java 7 you can do a try-Multicatch
try {
new Foo("").doSomething();
} catch (Exception1 | Exception2 e) {
e.printStackTrace();
}

order in multi-catch exception handler

I know since Java 7 you can use multi-catch but I wonder if the order of exceptions in it matters like in previous versions of java? E.g I put in Exception and then SQLException and IOException ?
try {
// execute code that may throw 1 of the 3 exceptions below.
} catch(Exception | SQLException | IOException e) {
logger.log(e);
}
Or should I do it this way ?
try {
// execute code that may throw 1 of the 3 exceptions below.
} catch(SQLException | IOException e) {
logger.log(e);
} catch(Exception e) {
logger.severe(e);
}
There's no point in a single catch block for catch(Exception | SQLException | IOException e) since Exception already covers its sub-classes IOException and SQLException.
Therefore catch(Exception e) would be enough if you wish the same handling for all of those exception types.
If you want different handling for the more general Exception, your second code snippet makes sense, and here the order of the two catch blocks matters, since you must catch the more specific exception types first.
Yes Order is important, it is from Child to Parent.
Refer this for more such.
The exception variable is implicitly final, therefore we cannot assign
the variable to different value within the catch block. For example,
the following code snippet will give a compile error
} catch (IOException | SQLException ex) {
ex = new SQLException();
}
The compiler will throw this error: multi-catch parameter ex may not be assigned
It is not allowed to specify two or more exceptions of a same
hierarchy in the multi-catch statement. For example, the following
code snippet will give a compile error because the
FileNotFoundException is a subtype of the IOException
} catch (FileNotFoundException | IOException ex) {
LOGGER.log(ex);
}
The compiler will throw this error (no matter the order is): Alternatives in a multi-catch statement cannot be related by subclassing
The Exception class is the supertype of all exceptions, thus we also
cannot write
} catch (IOException | Exception ex) {
LOGGER.log(ex);
}
Multi catch feature is provided in java to remove code duplication in two different hierarchical exceptions. If you are using it for this reason the ordering does not matter. If you are catching parent exception class Exception in multi catch block, then there is no need to add child exception IOException, SQLException classes.
The order matters, because if you try to catch Exception first, and your second catch is for IOException, obviously you'll never hit the second catch. So the order must be from the smallest Exception to the biggest.
The multicatch Exceptiontypes are separated by an 'OR', so no, the order doesn't matter.
You should only use the multicatch if you plan to have all the Exceptiontypes be handled the same way anyway, and if that's the case, the order doesn't matter.
EDIT: indeed, if the types are in a hiƫrarchical line, only the 'alternative' (in this case the generic Exception) type should be caught.
This has nothing to do with their order, though.
The Exceptions have some hierarchy. Exception e is more objective than others, because of that, it should be last exception that you handle.
There are no comparison between IOException and SQLException, because of that, you can handle them whatever you want.
So, the order should be:
try {
// execute code that may throw 1 of the 3 exceptions below.
} catch(SQLException | IOException e) {
logger.log(e);
} catch(Exception e) {
logger.severe(e);
}
or
try {
// execute code that may throw 1 of the 3 exceptions below.
} catch(SQLException e) {
logger.log(e);
} catch(IOException e){
logger.log(e);
} catch(Exception e) {
logger.severe(e);
}
or
try {
// execute code that may throw 1 of the 3 exceptions below.
} catch(IOException e) {
logger.log(e);
} catch(SQLException e){
logger.log(e);
} catch(Exception e) {
logger.severe(e);
}

Difference between catching exceptions using Exception class or FileNotFoundException class

Like i have these two scenarios where we have to handle FileNotFoundException
Case1:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Case2:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (Exception e) {
e.printStackTrace();
}
In both cases printed Stack Trace is same. I would like to know the difference between both implementations and what should be preferred ?
From the docs it gives the reason:
"A subclass inherits all the members (fields, methods, and nested
classes) from its superclass. Constructors are not members, so they
are not inherited by subclasses, but the constructor of the superclass
can be invoked from the subclass."
Exception class is the parent of all the other exception class. So if you know that you are going to get the FileNotFoundException then it is good to use that exception. Making the Exception is a generic call.
This would help you understand:
So as you can see that the Exception class is at a higher hierarchy, so it means it would catch any exception other than the FileIOExcetion. But if you want to make sure that an attempt to open the file denoted by a specified pathname has failed then you have to use the FileIOExcetion.
So here is what an ideal approach should be:
try {
// Lets say you want to open a file from its file name.
} catch (FileNotFoundException e) {
// here you can indicate that the user specified a file which doesn't exist.
// May be you can try to reopen file selection dialog box.
} catch (IOException e) {
// Here you can indicate that the file cannot be opened.
}
while the corresponding:
try {
// Lets say you want to open a file from its file name.
} catch (Exception e) {
// indicate that something was wrong
// display the exception's "reason" string.
}
Also do check this: Is it really that bad to catch a general exception?
In case 2, the catch block will be run for all Exceptions that are caught, irrespective of what exception they are. This allows for handling all exceptions in the same way, such as displaying the same message for all types of exceptions.
In case 1, the catch block will be run for FileNotFoundExceptions only. Catching specific exceptions in different catch blocks allows for the handling of different exceptions in different ways, such as displaying a different message to the user.
When an exception occures the JVM throws the instance of the Exception and that instance is passed to the respective catch block , so in catch(Exception e) e is just the reference variable , but the instance it points to is of Exception thrown .
In case of catch(FileNotFoundException e) , e is also a reference variable and the instance it points to is of Exception thrown , so in both cases different reference varibales (i.e. e) are pointing to the instance of same the Exception (which is thrown) .
this is what i prefer :
try {
// some task
} catch (Exception e) {
if (e instanceof FileNotFoundException) {
// do this
}
if (e instanceof NullPointerException) {
// do this
} else {
// do this
}
}
It is a matter of what you want to intercept. With Exception you will catch any exception but with FileNotFoundException you will catch only that error case, allowing the caller to catch and apply any processing.
When you write this:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
The code inside the catch block is only executed if the exception (thrown inside the try block) is of type FileNotFoundException (or a subtype).
When you write this, on the other hand:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (Exception e) {
e.printStackTrace();
}
the catch block is executed for any exception (since Exception is the root type of any exception).
If your file (test1.txt) does not exist, a FileNotFoundException is thrown and both code snippets are able to catch it.
Try and change it to something like:
try {
FileInputStream fis = new FileInputStream("test1.txt");
} catch (NullPointerException e) {
e.printStackTrace();
}
and you will see that the catch block is no longer executed.
Exception class is the parent of FileNotFoundException.
If you have have provided the Exception in the catch statement, every Exception will be handled in the catch block. But if FileNotFoundException is present in catch block, only exceptions rising due to absence of a File at said source or permissions not available to read the file or any such issues which makes spoils Java's effort to read the file will be handled. All other exceptions will escape and move up the stack.
In the code snippet provided by you, it is fine to use both. But i would recommend FileNotFoundException as it points to exact issue in the code.
For more detail you can read Go Here
Don't use any of those.
Don't catch Exception. Why? Because it also catches all unchecked exceptions (ie, RuntimeExceptions and derivates). Those should be rethrown.
Don't use the old file API. Why? Because its exceptions are unreliable (FileNotFoundException can be thrown if you try and open a file to which you have no read access to for instance).
Use that:
final Path path = Paths.get("test1.txt");
try (
final InputStream in = Files.newInputStream(path);
) {
// do something with "in"
} catch (FileSystemException e) {
// fs level error: no permissions, is a directory etc
} catch (IOException e) {
// I/O error
}
You do need to catch FileSystemException before IOException since the former is a subclass of the latter. Among other possible exceptions you can have: AccessDeniedException, FileSystemLoopException, NoSuchFileException etc.

How to best detect certain exceptions?

First of all: StackOverflow tells me that the question is subjective, which it is not.
I have this code:
try {
// Some I/O code that should work fine, but might go weird
// when the programmer fails or other stuff happens...
// It will also throw exceptions that are completely fine,
// such as when the socket is closed and we try to read, etc.
} catch (Exception ex) {
String msg = ex.getMessage();
if (msg != null) {
msg = msg.toLowerCase();
}
if (msg == null || (!msg.equals("pipe closed") &&
!msg.equals("end of stream reached") &&
!msg.equals("stream closed") &&
!msg.equals("connection reset") &&
!msg.equals("socket closed"))) {
// only handle (log etc) exceptions that we did not expect
onUnusualException(ex);
}
throw ex;
}
As you can see my procedure of checking for certain exceptions works, but is VERY dirty. I'm afraid that some VMs might use other strings for the exceptions that should NOT cause the specified method to be called.
What are different solutions I could use for this problem? If I use IOException to check for non-unusual (lol) exceptions, I will not catch any unusual exceptions that derive from it or use it.
For an exception that extends IOException (or another exception), put it in a separate catch statement before the Exception that it extends.
try {
// this might throw exceptions
} catch (FileNotFoundException e) { // this extends IOException
// code
} catch (IOException e) {
// more code
}
In the above example, the code in the first statement will be executed if the exception is an instance of FileNotFoundException. The second one will be executed only if it is an IOException that is not a FileNotFoundException. Using this approach, you can deal with multiple exception types that extend each other.
You can also catch multiple types of exceptions in the same catch statement.
try {
// even more code
} catch (IOException|ArithmeticException e) {
// this will run if an IOException or ArithmeticException is thrown
}
Hope this helps.

throws Exception in finally blocks

Is there an elegant way to handle exceptions that are thrown in finally block?
For example:
try {
// Use the resource.
}
catch( Exception ex ) {
// Problem with the resource.
}
finally {
try{
resource.close();
}
catch( Exception ex ) {
// Could not close the resource?
}
}
How do you avoid the try/catch in the finally block?
I usually do it like this:
try {
// Use the resource.
} catch( Exception ex ) {
// Problem with the resource.
} finally {
// Put away the resource.
closeQuietly( resource );
}
Elsewhere:
protected void closeQuietly( Resource resource ) {
try {
if (resource != null) {
resource.close();
}
} catch( Exception ex ) {
log( "Exception during Resource.close()", ex );
}
}
I typically use one of the closeQuietly methods in org.apache.commons.io.IOUtils:
public static void closeQuietly(OutputStream output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
// ignore
}
}
If you're using Java 7, and resource implements AutoClosable, you can do this (using InputStream as an example):
try (InputStream resource = getInputStream()) {
// Use the resource.
}
catch( Exception ex ) {
// Problem with the resource.
}
Arguably a bit over the top, but maybe useful if you're letting exceptions bubble up and you can't log anything from within your method (e.g. because it's a library and you'd rather let the calling code handle exceptions and logging):
Resource resource = null;
boolean isSuccess = false;
try {
resource = Resource.create();
resource.use();
// Following line will only run if nothing above threw an exception.
isSuccess = true;
} finally {
if (resource != null) {
if (isSuccess) {
// let close throw the exception so it isn't swallowed.
resource.close();
} else {
try {
resource.close();
} catch (ResourceException ignore) {
// Just swallow this one because you don't want it
// to replace the one that came first (thrown above).
}
}
}
}
UPDATE: I looked into this a bit more and found a great blog post from someone who has clearly thought about this more than me: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html He goes one step further and combines the two exceptions into one, which I could see being useful in some cases.
As of Java 7 you no longer need to explicitly close resources in a finally block instead you can use try-with-resources syntax. The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
Assume the following code:
try( Connection con = null;
Statement stmt = con.createStatement();
Result rs= stmt.executeQuery(QUERY);)
{
count = rs.getInt(1);
}
If any exception happens the close method will be called on each of these three resources in opposite order in which they were created. It means the close method would be called first for ResultSetm then the Statement and at the end for the Connection object.
It's also important to know that any exceptions that occur when the close methods is automatically called are suppressed. These suppressed exceptions can be retrieved by getsuppressed() method defined in the Throwable class.
Source: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Ignoring exceptions which occur in a 'finally' block is generally a bad idea unless one knows what those exceptions will be and what conditions they will represent. In the normal try/finally usage pattern, the try block places things into a state the outside code won't be expecting, and the finally block restores those things' state to what the outside code expects. Outside code which catches an exception will generally expect that, despite the exception, everything has been restored to a normal state. For example, suppose some code starts a transaction and then tries to add two records; the "finally" block performs a "rollback if not committed" operation. A caller might be prepared for an exception to occur during the execution of the second "add" operation, and may expect that if it catches such an exception, the database will be in the state it was before either operation was attempted. If, however, a second exception occurs during the rollback, bad things could happen if the caller makes any assumptions about the database state. The rollback failure represents a major crisis--one which should not be caught by code expecting a mere "Failed to add record" exception.
My personal inclination would be to have a finally method catch exceptions that occur and wrap them in a "CleanupFailedException", recognizing that such failure represents a major problem and such an exception should not be caught lightly.
One solution, if the two Exceptions are two different classes
try {
...
}
catch(package1.Exception err)
{
...
}
catch(package2.Exception err)
{
...
}
finally
{
}
But sometimes you cannot avoid this second try-catch. e.g. for closing a stream
InputStream in=null;
try
{
in= new FileInputStream("File.txt");
(..)// do something that might throw an exception during the analysis of the file, e.g. a SQL error
}
catch(SQLException err)
{
//handle exception
}
finally
{
//at the end, we close the file
if(in!=null) try { in.close();} catch(IOException err) { /* ignore */ }
}
Why do you want to avoid the additional block? Since the finally block contains "normal" operations which may throw an exception AND you want the finally block to run completely you HAVE to catch exceptions.
If you don't expect the finally block to throw an exception and you don't know how to handle the exception anyway (you would just dump stack trace) let the exception bubble up the call stack (remove the try-catch from the finally block).
If you want to reduce typing you could implement a "global" outer try-catch block, which will catch all exceptions thrown in finally blocks:
try {
try {
...
} catch (Exception ex) {
...
} finally {
...
}
try {
...
} catch (Exception ex) {
...
} finally {
...
}
try {
...
} catch (Exception ex) {
...
} finally {
...
}
} catch (Exception ex) {
...
}
After lots of consideration, I find the following code best:
MyResource resource = null;
try {
resource = new MyResource();
resource.doSomethingFancy();
resource.close();
resource = null;
} finally {
closeQuietly(resource)
}
void closeQuietly(MyResource a) {
if (a!=null)
try {
a.close();
} catch (Exception e) {
//ignore
}
}
That code guarantees following:
The resource is freed when the code finished
Exceptions thrown when closing the resource are not consumed without processing them.
The code does not try to close the resource twice, no unnecessary exception will be created.
If you can you should test to avoid the error condition to begin with.
try{...}
catch(NullArgumentException nae){...}
finally
{
//or if resource had some useful function that tells you its open use that
if (resource != null)
{
resource.Close();
resource = null;//just to be explicit about it was closed
}
}
Also you should probably only be catching exceptions that you can recover from, if you can't recover then let it propagate to the top level of your program. If you can't test for an error condition that you will have to surround your code with a try catch block like you already have done (although I would recommend still catching specific, expected errors).
You could refactor this into another method ...
public void RealDoSuff()
{
try
{ DoStuff(); }
catch
{ // resource.close failed or something really weird is going on
// like an OutOfMemoryException
}
}
private void DoStuff()
{
try
{}
catch
{
}
finally
{
if (resource != null)
{
resource.close();
}
}
}
I usually do this:
MyResource r = null;
try {
// use resource
} finally {
if( r != null ) try {
r.close();
} catch( ThatSpecificExceptionOnClose teoc ){}
}
Rationale: If I'm done with the resource and the only problem I have is closing it, there is not much I can do about it. It doesn't make sense either to kill the whole thread if I'm done with the resource anyway.
This is one of the cases when at least for me, it is safe to ignore that checked exception.
To this day I haven't had any problem using this idiom.
try {
final Resource resource = acquire();
try {
use(resource);
} finally {
resource.release();
}
} catch (ResourceException exx) {
... sensible code ...
}
Job done. No null tests. Single catch, include acquire and release exceptions. Of course you can use the Execute Around idiom and only have to write it once for each resource type.
Changing Resource from best answer to Closeable
Streams implements Closeable Thus you can reuse the method for all streams
protected void closeQuietly(Closeable resource) {
if (resource == null)
return;
try {
resource.close();
} catch (IOException e) {
//log the exception
}
}
I encountered a situation similar where I couldn't use try with resources but I also wanted to handle the exception coming from the close, not just log and ignore it like closeQuietly mechanism do. in my case I'm not actually dealing with an output stream, so the failure on close is of more interest than a simple stream.
IOException ioException = null;
try {
outputStream.write("Something");
outputStream.flush();
} catch (IOException e) {
throw new ExportException("Unable to write to response stream", e);
}
finally {
try {
outputStream.close();
} catch (IOException e) {
ioException = e;
}
}
if (ioException != null) {
throw new ExportException("Unable to close outputstream", ioException);
}

Categories