Catch specific exceptions and do same stuff under all of them? - java

I see below code in my legacy project where i am catching different types of exception and intention is just to logg them
try {
//somecode
}
catch (ProjectExceptionException1 e) {
log.error(e.getMessage(), e);
}
catch (ProjectExceptionException2 e) {
log.error(e.getMessage(), e);
}
catch (Exception e) {
log.error(e.getMessage(), e);
}
My point is if requirement is just to log the exception(whether its checked or unchecked), above code should be replaced by below one
that makes code simple and more readable. As per my understanding there is not point of catching specific exception and doing
same stuff under all. Is n't it? Let me know if i am missing something here.
try {
//somecode
}
catch (Exception e) {
log.error(e.getMessage(), e);
}
UPDATE:- even if are throwing specific exception on UI just to display the stack trace like below. Even then it does not make sense
.Basically if we want to handle the specific exception in special way then it would make sense. Right?
try {
//somecode
}
catch (ProjectExceptionException1 e1) {
throw e1;
}
catch (ProjectExceptionException2 e2) {
throw e2;
}
catch (Exception e3) {
throw e3;
}

Yes, it is perfectly fine to replace the top block with the single catch (Exception e), as long as you are only logging and do not need any Exception-specific handling.

As of Java 7 you can catch multiple exceptions and handle them all in the same way using the syntax:
catch (ProjectExceptionException1 | ProjectExceptionException2 ex)
So, if you want to log some exceptions but act on others, you could group the behaviours in this manner, assuming that the actions you would like to perform are the same. e.g. print stack trace then log for ProjectExceptionException1 and ProjectExceptionException2, but only log for everything else.

If you can upgrade the code to java 1.7, you could use the new multi-catch feature. It could look like this:
try {
//somecode
}
catch (ProjectExceptionException1 | ProjectExceptionException2 e) {
log.error(e.getMessage(), e);
}
You may want to reconsider catching Exception and only catching exceptions that you know would be thrown by the code in the try block so you don't just resort to logging unexpected exceptions.
Here's a link that goes into more detail about the feature with examples: http://www.oracle.com/technetwork/articles/java/java7exceptions-486908.html

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();
}

catching exception in catch block

What is difference between
try {
...
} catch (Nullpointerexception e) { ... }
} catch (Exception e) { ... }
and
try {
...
} catch (Exception e) { ... }
Suppose I have a NullPointerException, which one is best? And why?
Q: What is difference between catch(Nullpointerexception e) and catch(Exception e)?
A: The one former is specific, the latter is general.
There are times when you want to handle specific classes of exceptions (like "NullPointerException") one way, but different classes of exception (like "IOException") differently.
In general, you should should choose to handle the "narrowest" exception possible, rather than "handle everything".
Another significant difference between "NullPointerException" (and "ArrayIndexOutOfBound") vs. many other exceptions is that NullPointerException is an unchecked exception.
Note, too, that in Java 7 you can how catch multiple different exceptions in the same catch block:
Catching Multiple Exceptions in Java 7
// Pre-Java 7 code:
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);
}
But now...
// Java 7 and higher
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);
}
You should use the second option if the code to handle Exception is always the same, and the first one if you want different behaviours for different Exceptions.
In any case, is very rare to need a catch clause for NullPointerExceptions, because you can simply avoid them with a null check in your code (you'll really need a catch clause only if the NullPointerException is generated in code you cannot control, for example in the internals of a library).
Starting from Java 7, you can even do:
try {
...
} catch (NullPointerException | AnotherException e) {
...
}
to avoid replicating the same body for different Exception classes.
Prior to Java 7, you have to include the Exception handling code in a method and call if from multiple catch clauses to avoid its replication.

Is there a way to suppress the "catch branch identical" warning? Unable to use multi catch in this instance

Working on an android application with API 17 and currently needing to do some reflection to complete a task. The ReflectiveOperationException is only available for use from API 19 and up, however this is fine since I can simply catch each exception individually.
The problem is when I do, I get a warning saying the catch branches are identical and can be written using a multi-catch (or use Exception which I'd like to avoid). But when I write the catches as a multi-catch, I get the error saying I can't use the ReflectiveOperationException class due to not being API 19.
Simply put I'd like to just suppress the warning but wasn't able to find anything that matches besides just doing #SuppressWarning("all")
For context, here are the warnings/errors:
// Error: "Multi-catch with these reflection exceptions requires API level 19 (current min is 15)
// because they get compiled to the common but new super type ReflectiveOperationException.
// As a workaround either create individual catch statements, or catch Exception."
try {
return someMethodThatThrowsExceptions();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
// Warning: 'catch' branch identical to 'InstantiationException | IllegalAccessException' branch"
try {
return someMethodThatThrowsExceptions();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
Edit: added all the catches I was dealing with, originally only had two
#SuppressWarnings("TryWithIdenticalCatches") should do the trick.
For suppressing certain warnings I have a utility function like this:
public static <T> T get( T value )
{
return value;
}
So, you can feed e to this get() function before throwing it, thus making the two catch clauses non-equal.

Should we write catch(Exception e) for every try catch block in java

My question is should we have catch(Exception e) for every try - catch block. Knowing that it will catch all exceptions .... is this type of coding recommended in java or should i only catch exceptions that are known to occur.
Consider the below example.
try {
//something
} catch (NumberFormatException ne) {
//do something
} catch (Exception e) {
log.error(e);
}
No. This is not a good practice. Identify exceptions that will be thrown before implementation. Catch only those exceptions that you are throwing from your method.
Thoroughly unit test your code and identify them.
Yes. you can keep multiple catch for one try. But the hierarchy should be more specific to generic type.
Also i totally agreed sith Tejas's answer.

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);
}

Categories