In a project I am working at, I have found a class which wraps all methods of its super-class in some elaborate exception handling. It looks similar to that:
public void method1() throws ExceptionA {
String exceptionString = "";
try {
super.method1();
} catch (ExceptionA e) {
exceptionString = // <convert the exception to string in an elaborate way>
throw e;
} finally {
// <an elaborate logger call which uses value of exceptionString>
}
}
public void method2() throws ExceptionB, ExceptionC {
String exceptionString = "";
try {
super.method2();
} catch (ExceptionB | ExceptionC e) {
exceptionString = // <convert the exception to string in elaborate way>
throw e;
} finally {
// <an elaborate logger call which uses value of exceptionString>
}
}
// ... <a bunch of other methods like this>
I immediately though "Wow, how could would it be to have one generic wrapper and just call it in every of these methods. The class would be like 10x shorter!". So I got to work.
This is where I got stuck:
private interface ThrowingMethod<E extends Exception> {
void run() throws E;
}
public <E extends Exception> void wrapMethod(ThrowingMethod<E> method) throws E {
String exceptionString = "";
try {
method.run();
} catch (Exception e) {
exceptionString = // <convert the exception to string in an elaborate way>
throw e;
} finally {
// <an elaborate logger call which uses value of exceptionString>
}
}
public void method1() throws ExceptionA {
wrapMethod(super::method1); // works
}
public void method2() throws ExceptionB, ExceptionC {
wrapMethod(super::method2); // Error in Eclipse: "Unhandled exception type Exception"
}
// ... <a bunch of other methods like this>
In conclusion, this approach works for methods that throws only one type of checked exception. When method throws multiple checked exceptions, Java assumes that the exception type is Exception.
I tried to add more generic parameters to ThrowingMethod and wrapMethod but it doesn't change anything.
How can I get a functional interface to work with multiple generic exceptions?
wrapMethod()would need to support multiple exceptions in its throws-clause in order to call it like inmethod2()and have that throwExceptionBand/orExceptionC. So you might need to provide overloads for more than one exception (probably not that many since IMO a method with 20 exceptions in its throws-clause is bad design anyways ). Since you'd need multiplewrapMethod()'s you'd probably need to extract the conversion and logging parts into separate methods - if possible. - Thomasmethod1still works and wrappingmethod2still defaults toException. So it won't work, unless you are suggesting that I should make a separate wrapper for each possible number of exceptions but this would defeat the point of this exercise which is the make the code shorter. - NO_NAMEinterface ThrowingMethod<E extends Exception>, notinterface <E extends Exception> ThrowingMethod. Further, there is no need to declare interfaces asstatic. That’s always implied. - Holgerjavac- Holger