I'm working on some server-side code that wraps all exceptions before passing them to the client side, due to this all client facing methods have the following code
try{
DoSomething();
} catch (ExceptionA e) {
throw new CustomException(AType, e);
} catch (ExceptionB e) {
throw new CustomException(BType, e);
} catch (Exception e) {
throw new CustomException(Unexpected, e);
}
to have this repeated in every method seems to violate the DRY principle and I was wondering what the best way to refactor it would be. For instance I was thinking a wrapper method such as:
private void wrapException(Exception e) {
if (e instanceof ExceptionA) {
throw new CustomException(AType, e);
}
etc...
Take a look at AspectJ soften exception.
Also look at Guava's Throwables.
There is also Lamboks sneaky exception.
The other option is to use Anonymous object instances aka closures.
public abstract class Wrapper {
public void execute() {
try {
// do some boiler plate before
this.wrap();
// do some boiler plate after.
} catch (ExceptionA | ExceptionB ex) {
Type t = determineType(ex);
throw new CustomException(t, ex);
}
}
public void abstract wrap();
}
Now in your code you do something like:
new Wrapper() {
public void wrap() {
DoSomething();
}
}.execute()
This is possible in Java7 and up:
http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
Copy-paste example from above doc:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
This is one way to go about it:
Exception caughtEx = null;
String extraInfo = null;
try{
DoSomething();
} catch (ExceptionA e) {
caughtEx = e;
extraInfo = AType;
} catch (ExceptionB e) {
caughtEx = e;
extraInfo = BType;
} catch (Exception e) { // catching Exception is usually a bad idea, just let it bubble up without catching...
caughtEx = e;
extraInfo = Unexpected;
}
if (caughtEx != null) throw new CustomException(extraInfo, caughtEx);
Related
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);
i'm struggling to figure out how to use the Closer utility from the guava library. Please see the code below.
One thing is, that the IndexWriter throws an IOException on both object initialization and close(). Therefore, the code in the finally and rethrow blocks is underlined.
The other question is, why do i have to catch Throwable instead of other exception types and do i have to rethrow the errors (i would prefer to log those at the spot)
`
int getDocumentsCount() {
Closer closer = Closer.create();
try {
IndexWriter iwriter = closer.register(openIndexWriter());
return iwriter.numDocs();
} catch (Throwable e) {
logger.error(e, e);
return -1;
} finally {
closer.close();
}
}
IndexWriter openIndexWriter() throws IOException {
return new IndexWriter(directory, analyzer, false,
IndexWriter.MaxFieldLength.UNLIMITED);
}
`
Thanks a lot
(stuck with Java 6)
From Guava's own explanation, you have to use Throwable, yes.
Here's their example snippet:
public void foo() throws IOException {
Closer closer = Closer.create();
try {
InputStream in = closer.register(openInputStream());
OutputStream out = closer.register(openOutputStream());
// do stuff with in and out
} catch (Throwable e) { // must catch Throwable
throw closer.rethrow(e);
} finally {
closer.close();
}
}
Note that they catch Throwable and rethrow it directly from the Closer instance.
As to why it is Throwable and not, let's say IOException or RuntimeException, it's because the Closer must know that an error occurred so that it can close the resources properly. All is only a matter of doing things proper. So it can work if you don't do it properly, but it's not guaranteed.
Not that if your method can throw MyOwnCheckedException, for instance, you have to declare them:
} catch (Throwable t) {
throw closer.rethrow(e, MyOwnCheckedException.class);
} finally {
closer.close();
}
Java 7 example, for comparison:
public void foo() throws IOException {
try (InputStream in = openInputStream();
OutputStream out = openOutputStream();
// do stuff with in and out
}
}
If you compare the Closer example with the Java 7 example, you can see that I still have to declare the IOException in the method signature.
For your case, this is what you have to do:
int getDocumentsCount() {
try {
Closer closer = Closer.create();
try {
IndexWriter iwriter = closer.register(openIndexWriter());
return iwriter.numDocs();
} catch (Throwable e) {
closer.rethrow(e);
} finally {
closer.close();
}
} catch (IOException e) {
logger.error(e, e);
return -1;
}
}
To avoid try-pyramids, I'd do the following:
int getDocumentsCount() {
try {
return doGetDocumentsCount();
} catch (IOException e) {
logger.error(e, e);
return -1;
}
}
int doGetDocumentsCount() throws IOException {
Closer closer = Closer.create();
try {
IndexWriter iwriter = closer.register(openIndexWriter());
return iwriter.numDocs();
} catch (Throwable e) {
closer.rethrow(e);
} finally {
closer.close();
}
}
I have a lot of custom exceptions that I'm throwing in a specific cases in the code, and I'd like to have one catch block at the bottom of the method to handle them all.
All the exceptions are children of the Exception class CribbageException, so I'd like to have:
public void myMethod(){
if (whatever){
throw new CardException();
}
if (something else){
throw new InvalidCardException();
}
if (scenario 3){
throw new TwoCardsException();
}
catch (CribbageException e) {
System.out.println(e.getMessage());
}
}
But I'm getting a catch without try error.
Is there any way to use this type of exception handling?
Wrap all the throws inside a single try.
public void myMethod(){
try {
if (whatever){
throw new CardException();
}
if (something else){
throw new InvalidCardException();
}
if (scenario 3){
throw new TwoCardsException();
}
}
catch (CribbageException e) {
System.out.println(e.getMessage());
}
}
when I debug the below code, there is an SmbException and goes catch block line sb.append(pLogger.reportError(pStr, e));, but it does not go into the method reportError().
what is the reason behind this. please advise if any changes.
try {
sfos = new SmbFileOutputStream(sFile);
} catch (SmbException e) {
sb.append(pLogger.rError(pathStr, e));
}
below is rError() method
public String rError(String pxString,Exception e){
String errorToMailStr=null;
abcd="Verifying # "+pxString+"::Error ["+e.getMessage()+"]";
logger.debug("Error when verifying # "+pxString+":Error ["+gMsg(e)+"]");
return abcd;
}
at line logger.debug("Issue "+pxString+":Error ["+gMsg(e)+"]");
is going to below method and ends.
public abstract class ReflectiveCallable {
public Object run() throws Throwable {
try {
return runReflectiveCall();
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
Based on what you have revealed here, there is a problem in getExceptionMsg()
As we know Java uses erasure, so any Generic class cannot do
T t = new T();
So I was trying out Java reflection to have a class with Static methods, to instantiate any Class with any Constructor. Here is the code.
import java.lang.reflect.*;
public class GenericNewInstance {
public static <T> T createInstance(Class<T> cObj) {
try {
return cObj.newInstance();
} catch (InstantiationException e) {
System.out.println("Instantiation Exception");
return null;
} catch (IllegalAccessException e) {
System.out.println("Illegal Access Exception");
return null;
}
}
public static <T> T createInstanceUsingRelection(Class<T> c, Object... initArgs) {
Constructor<T> cTor = null;
Class<?>[] cObjs = new Class<?>[initArgs.length];
int i = 0;
for(Object o : initArgs) {
cObjs[i++] = o.getClass();
}
try {
cTor = c.getConstructor(cObjs);
} catch (SecurityException e) {
System.out.println("security exception. Cannot get Constructor");
return null;
} catch (NoSuchMethodException e) {
System.out.println("NoSuchMethodException Cannot get constructor");
return null;
}
try {
return cTor.newInstance(initArgs);
} catch (IllegalArgumentException e) {
System.out.println("Illegal Argument Exception");
return null;
} catch (InstantiationException e) {
System.out.println("Instantiation Exception");
return null;
} catch (IllegalAccessException e) {
System.out.println("Illegal Access Exception");
return null;
} catch (InvocationTargetException e) {
System.out.println("Invocation Target Exception");
return null;
}
}
}
Example for using this.
Integer i = GenericNewInstance.createInstanceUsingRelection(Integer.class, "0");
So my questions:
Is this the right way to implement it? (or is it verbose?)
What are the typical use cases of doing this?
Can/Should we avoid using Reflection while using Generics?
Your code will fail at c.getConstructor(cObjs) since this doesn't take into account the type hierarchy. If any argument is a subtype of the constructor's declared param type, this call will not return it. You'll need quite a lot more type juggling to get it working. I advise you to take a look at the code that already solves this problem. Perhaps you can even use that library as-is, your choice. It's the implementation code for Clojure, a JVM-based dynamic language that needs exactly this stuff. The library is available from the Maven central repo.
BTW Your exception handling is redundant. Either just declare throws Exception or catch any Exception and wrap it in a RuntimeException. When something fails, the original exception is the best diagnostic.