Reputation: 129
I have written a method which is returning some value in try statement. Inside catch I am calling handleException which will have conversion logic of understanding the exception and rethrowing new exception. Here handleException is always throwing exception, still the getXYZ() gives compile time error expecting return statement. I am not handling the exception, I am just throwing new exception so why does the method wants return statement.
public String getXYZ(String input) {
try {
return getFromDAO(input);
} catch (Exception e) {
handleException(e);
}
}
private void handleException(Exception e) {
try {
throw e;
} catch(SomeException se) {
throw new MyRuntimeException("MyException message", se);
} catch(SomeOtherException soe) {
throw new MyRuntimeException("MyException message", soe);
}
}
The other version of this method compiles.
public String getXYZ(String input) {
try {
return getFromDAO(input);
} catch (Exception e) {
throw e;
}
}
Upvotes: 0
Views: 889
Reputation: 5105
You may want to consider using the new java 8 lambda features to solve your problem as well. You will have to create a functional interface to declare the signature of the lambdas (with the relevant exceptions). Your handleException method will now be the one who runs the lambda and handles the exceptions.
public String getXYZ(String input) {
return handleKnownExceptions(() -> getFromDAO(input));
}
private <T> T handleKnownExceptions(ThrowingCode<T> throwingCode)
{
try {
return throwingCode.get();
} catch(SomeException se) {
throw new MyRuntimeException("MyException message", se);
} catch(SomeOtherException soe) {
throw new MyRuntimeException("MyException message", soe);
}
}
@FunctionalInterface
public interface ThrowingCode<T>
{
T get() throws SomeException, SomeOtherException;
}
Upvotes: 1
Reputation: 533530
One way to solving this is making it clear to the compiler that you expect an exception to be thrown.
public String getXYZ(String input) {
try {
return getFromDAO(input);
} catch (Exception e) {
throw handleException(e); // compiles ok.
}
}
private RuntimeException handleException(Exception e) {
try {
throw e;
} catch(SomeException se) {
return new MyRuntimeException("MyException message", se);
} catch(SomeOtherException soe) {
return new MyRuntimeException("MyException message", soe);
} catch(RuntimeException re) {
return re;
} catch(Exception e2) {
return new MyRuntimeException("MyException message", e2);
}
}
BTW an alternative approach is to not wrap the Exception at all and leave the exception as it was.
public String getXYZ(String input) {
try {
return getFromDAO(input);
} catch (Exception e) {
throw rethrow(e); // compiles ok.
}
}
/**
* Cast a CheckedException as an unchecked one.
*
* @param throwable to cast
* @param <T> the type of the Throwable
* @return this method will never return a Throwable instance, it will just throw it.
* @throws T the throwable as an unchecked throwable
*/
@SuppressWarnings("unchecked")
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
throw (T) throwable; // rely on vacuous cast
}
Upvotes: 1
Reputation: 5105
There is a pattern I have seen a few times to handle this situation. You let the handleException
method declare that it returns an exception. This is only indicative though, it will never return anything, it will always throw, just as before. The declared return type will allow the caller to use a throw handleException()
statement, which will keep the compiler happy. The resulting code will be:
public String getXYZ(String input) throws Exception {
try {
return getFromDAO(input);
} catch (Exception e) {
throw handleException(e);
}
}
/**
* This method will never return normally, always throws.
*/
private Exception handleException(Exception e) throws Exception
{
try {
throw e;
} catch(SomeException se) {
throw new MyRuntimeException("MyException message", se);
} catch(SomeOtherException soe) {
throw new MyRuntimeException("MyException message", soe);
}
}
Upvotes: 0
Reputation: 14500
You are not throwing anything in the catch
block, you're calling your handle function, which ultimately will result in a new exception being thrown, but the actual code in getXYZ
is doing a function call in catch
. What if you change handleException
to later not throw an exception in some circumstances, what would getXYZ
return then?
Upvotes: 5