How to manage catches with the same behavior - java

I have a piece of code that can throw three different types of exceptions. Two of these exceptions are handled in a certain way while the third is handled in another way. Is there a good idiom for not cutting and pasting in this manner?
What I would like to do is:
try { anObject.dangerousMethod(); }
catch {AException OR BException e) { /*do something*/ }
catch {CException e) { /*do something else*/ }

There is in JDK 7, but not in earlier Java versions. In JDK 7 your code could look like this:
try { anObject.dangerousMethod(); }
catch {AException | BException e) { /*do something*/ }
catch {CException e) { /*do something else*/ }

As defined by new Java 7 specifications you can now have.
try { anObject.dangerousMethod(); }
catch {AException | BException e) { /*do something*/ }
catch {CException e) { /*do something else*/ }

Java 6 doesn't support specifying catch blocks this way. Your best bet would be to define a super-class/interface for those two exception types and catch the super-class/interface. Another simple solution would be to have a method which contains the logic for handling those two exceptions and call that method in the two catch blocks.

How about defining a custom Exception (let's say DException) that extends both AException and BException, then use it in your code:
try { anObject.dangerousMethod(); }
catch {DException e) { /*do something*/ }
catch {CException e) { /*do something else*/ }

Related

How to wrap different methods with same try catch block?

I have functions with the same param and response type like;
public ResponseType functionA(ParamType) throws Exception1
public ResponseType functionB(ParamType) throws Exception1
and I call these functions from different places with the same repeating try/catch block. Is there any way to reduce the duplicate code?
try{
return functionA(obj);
} catch (Exception1 e) { .... }
catch (Exception2 e) { .... }
catch (Exception3 e) { .... }
try{
return functionB(obj);
} catch (Exception1 e) { .... }
catch (Exception2 e) { .... }
catch (Exception3 e) { .... }
I have tried to create a function like below, but I am getting
Exception e1 is never thrown in try block
as expected.
public ResponseType callFunction(Function<ParamType, ResponseType> function, ParamType obj) {
try{
return function.apply(obj)
}catch (Exception1 e) { .... }
catch (Exception2 e) { .... }
catch (Exception3 e) { .... }
}
The issue is that Function.apply is not declared to throw any exceptions, so it is not generally possible to throw checked exceptions from an implementation, or to catch a checked exception from it at a call site. (Ignoring unusual workarounds as mentioned in the comments.)
However, Java does not restrict lambda expressions to only be used with standard functional interfaces, so the best approach when you need to handle specific exception types is to create your own.
#FunctionalInterface
interface MyFunction {
ResponseType apply(ParamType param) throws Exception1, Exception2, Exception3;
}
This can be used in a similar way to java.util.function.Function:
public ResponseType callFunction(MyFunction function, ParamType obj) {
try{
return function.apply(obj);
}
catch (Exception1 e) { throw new RuntimeException("Exception1"); }
catch (Exception2 e) { throw new RuntimeException("Exception2"); }
catch (Exception3 e) { throw new RuntimeException("Exception3"); }
}
(Modified to throw runtime exceptions in the catch blocks so that this will compile)
The calling code is identical to any standard functional interface:
callFunction(this::functionA, obj);
callFunction(this::functionB, obj);
or, equivalently:
callFunction(param -> functionA(param), obj);
callFunction(param -> functionB(param), obj);

Exception handling practices of multiple exception throwing functions

If I have multiple functions in a function which are throwing exceptions what's the best way of handling them if they depend on each other?
With depending on each other I mean that if something throws an exceptions the code after the function which threw the exception should be skipped.
I figured out three ways to do this:
Exception nesting
public void parent() {
someFunction();
}
public void someFunction() {
try {
function1();
try {
function2();
...
} catch (Func2xception e) {
System.out.println("Function 2 failed!");
}
} catch (Func1Exception e) {
System.out.println("Function 1 failed!");
}
}
Return on exception
public void parent() {
someFunction();
}
public void someFunction() {
try {
function1();
} catch (Func1Exception e) {
System.out.println("Function 1 failed!");
return;
}
try {
function2();
} catch (Func2xception e) {
System.out.println("Function 2 failed!");
return;
}
...
}
Add exceptions to method signature
public void parent() {
try {
someFunction();
} catch (Func1Exception e) {
System.out.println("Function 1 failed!");
} catch (Func2Exception e) {
System.out.println("Function 2 failed!");
} ...
}
public void someFunction() throws Func1Exception, Func2Exception {
function1();
function2();
...
}
I sometimes use all of them together and that's a mess. Are there any good practices on how to handle situations like this?
The way to use depends on whether the exceptions should be handled by the client of the someFunction() method or else caught and handled as soon as they happen, that is, inside the someFunction() method.
In the exception nesting case, the nesting is not required.
You can use a single try statement and place the two calls that may generate the exceptions in it.
If an exception occurs in one of the two invoked methods, you finish in one of the catch statements and so the second method is executed only if the first one has not thrown the caught exception.
It produces exactly the same result than your code but with a single try and without nesting that is less readable.
public void someFunction() {
try {
function1();
function2();
...
} catch (Func1Exception e) {
System.out.println("Function 1 failed!");
}
catch (Func2xception e) {
System.out.println("Function 2 failed!");
}
}
This way of doing is suitable if you have some other instructions after the catch statements and you want them to be executed even if one of the expected exceptions was caught.
The return on exception case manifests a close enough problem.
It may be refactored with a single try :
public void someFunction() {
try {
function1();
function2();
...
} catch (Func1Exception e) {
System.out.println("Function 1 failed!");
return;
}
catch (Func2xception e) {
System.out.println("Function 2 failed!");
return;
}
}
...
}
This way of doing is suitable if you have some other instructions after the catch statements and you don't want them to be executed if one of the expected exceptions was caught.
Nevertheless for these two cases, if the exception handling is the same for the two exceptions (Func1Exception and Func2xception), you could group them in a single catch statement :
public void someFunction() {
try {
function1();
function2();
...
}
catch (Func1Exception | Func2xception e) {
System.out.println("Function 1 or 2 failed!");
}
}
At last, the add exceptions to method signature case makes sense only if the exceptions should be handled by the client of the method.
You can catch multiple exceptions in one catch clause, starting from Java 7 I believe.
try {
...
} catch(IOException | IllegalArgumentException | SomeOtherException e) {
...
}

Multiple Catch blocks vs Catching in Base Exception class

Assuming we are talking about all the exceptions that extends base Exception class,
is:
try {
some code;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
catch (MyOwnException e)
{
e.printStackTrace();
}
same as:
try {
some code;
}
catch (Exception e) {
e.printStackTrace();
}
I am wondering in which case I MUST use the former one?
In the 2nd option Exception will catch all exception, not only those explicitly listed in the first option.
Use the 1st option if you want to catch only selected exceptions, and respond differently to each.
If you want to catch only selected exceptions, and have the same response to all of them, you could use:
catch (InterruptedException | ExecutionException | MyOwnException e)
{
e.printStackTrace();
}
It is good practice to use Exception sub classes rather than Exception class. If you use Exception then it would be difficult to debug.
Here is a link for reference
http://howtodoinjava.com/best-practices/java-exception-handling-best-practices/#3
If you have multiple exceptions which all are extending from...we'll say IndexOutOfBoundsException, then unless you specifically want to print a different message for StringIndexOutOfBoundsException or another sub-class you should catch an IndexOutOfBoundsException. On the other hand if you have multiple exceptions extending from the Exception class, it is proper format to create a multi-catch statement at least in JDK 1.8:
try {
// Stuff
}catch(InterruptedException | ClassNotFoundException | IOException ex) {
ex.printStackTrace();
}
The former one where you create multiple catch statements is if you were trying to do what I said before.
try {
// Stuff
}catch(StringIndexOutOfBoundsException se) {
System.err.println("String index out of bounds!");
}catch(ArrayIndexOutOfBoundsException ae) {
System.err.println("Array index out of bounds!");
}catch(IndexOutOfBoundsException e) {
System.err.println("Index out of bounds!");
}

In a Try block, is it better to create one Catch for multiple exceptions OR one Catch for each exception?

I am curious which one is more practical, and which cases do we need to use the first and where we need to use the second? For example in Java7:
first.java
try {
/* some code that throws these exceptions */
} catch (NoSuchAuthorityCodeException e) {
throw new MyAPIException("Something went wrong", e);
} catch (FactoryException e) {
throw new MyAPIException("Something went wrong", e);
} catch (MismatchedDimensionException e) {
throw new MyAPIException("Something went wrong", e);
} catch (TransformException e) {
throw new MyAPIException("Something went wrong", e);
}
second.java
try {
/* some code that throws these exceptions */
} catch (NoSuchAuthorityCodeException | FactoryException| MismatchedDimensionException | TransformException e) {
/*handle all exceptions*/;
}
Do you need to handle each exception differently? If yes, have different catch blocks with different behaviors. If you want to handle all the exceptions in the same way, one catch block is fine.
Perfectly answered by TangledUpInBlue, If only you need to handle it differently and want different actions on different types of actions, use individual catches.
Otherwise use the parent class Exception, one for all:
try{
}
catch(Exception e){
}

Best practice for handling multiple exceptions in similar ways in Java

Is there a canonical best-way-to-do-this for the following situation?
I have a block of code that can generate a number of different exceptions, each of which is handled by hiding a dialog, displaying an error message and running an onDisconnect() method. The catch is that, for each exception, the error message needs to be different. As I see it, there are two choices. The first is to catch Exception, then handle the various exceptions inside the catch block using instanceof, like so:
} catch (Exception e) {
dialog.dismiss();
String errorMessage = getString(R.string.default_error);
if (e instanceof ArrayIndexOutOfBoundsException)
errorMessage = getString(R.string.bad_host);
else if (e instanceof UnknownHostException)
errorMessage = getString(R.string.unknown_host);
else if (e instanceof NumberFormatException)
errorMessage = getString(R.string.bad_port);
else if (e instanceof IOException)
errorMessage = getString(R.string.no_connection);
showError(errorMessage);
onDisconnect();
}
The other option is to catch all of them separately, like so:
} catch (ArrayIndexOutOfBoundsException e) {
dialog.dismiss();
showError(getString(R.string.bad_host));
onDisconnect();
} catch (UnknownHostException e)
dialog.dismiss();
showError(getString(R.string.unknown_host));
onDisconnect();
} // ...etc.
Is there a preferred way to do this? I opted for the first case (at least for now) because it minimizes duplicated code, but I've also heard that instanceof and catch (Exception) are the works of Satan.
My preference is to have a separate method like this:
void handleException(String msg) {
dialog.dismiss();
showError(getString(msg));
onDisconnect();
}
and then in your code that throws the exception just like this:
} catch (ArrayIndexOutOfBoundsException e) {
handleException(getString(R.string.bad_host));
} catch (UnknownHostException e)
handleException(getString(R.string.unknown_host));
} // ...etc.
You want to catch them separately. If you catch the generic Exception, you might end up catching Exceptions that you're not expecting (that could be pushed up from somewhere else in the stack for example) and you're stopping them from propagating up to wherever they were actually meant to be handled.
(Later edit): You may also want to look into using finally to avoid some of the code repetition problem.
make a (private void) method for handling the error. You may be required to pass it in some parameters about what's going on, but the behavior will be consistent. When you make a change to the method it changes all places where it's used, so you get to reduce your boilerplate code.
try {
// stuff
} catch(OneException) {
handleSimilarExceptions();
} catch(TwoException) {
handleSimilarExceptions();
} catch(DifferentException) {
log.write("Something wierd happened, handling it");
somethingDifferent();
}
What if you do smth like modified second version:
catch (ArrayIndexOutOfBoundsException e) {
handleException(R.string.bad_host);
} catch (UnknownHostException e)
handleException(R.string.unknown_host);
} // ...etc.
void handleException(String s) {
dialog.dismiss();
showError(getString(s));
onDisconnect();
}
And I agree, instanceof usage like this is a work of Satan...

Categories

Resources