Is it possible to have a general exception wrapper like this?
public Function<?, Optional<?>> ExceptionWrapper = (? input) -> {
try {
return Optional.of(someAction(input));
} catch (Exception e) {
logger.warn(e.getMessage());
}
return Optional.empty();
};
These ?
s can be have different types, similar to Any
in TS.
The purpose is not repeating the same code.
It might be just a bad practice.
You can use a method like this:
public static <T> Optional<T> wrappException(SupplierWithException<T> supplierThatThrowsException) {
try {
return Optional.of(supplierThatThrowsException.get());
}
catch (Exception e) {
//logger.warn(e.getMessage()); //TODO add a real logger here
System.err.println("logger warning: " + e.getMessage());
}
return Optional.empty();
};
This method gets a SupplierWithException<T>
as parameter, that is then executed. Therefore you need to create the functional interface SupplierWithException<T>
like this:
@FunctionalInterface
public interface SupplierWithException<T> {
public T get() throws Exception;
}
Now the method can be used like this (assuming the method is defined in the class ExceptionWrapperUtil):
public static void main(String[] args) {
Optional<Integer> result1 = ExceptionWrapperUtil.wrappException(//
//create a SupplierWithException object (as lambda expression, because it's a functional interface)
//when the get() method is called (within the wrappException method) the calculation is started
() -> {
return doCalculations(true);//will throw an exception that is logged
});
Optional<Integer> result2 = ExceptionWrapperUtil.wrappException(() -> {
return doCalculations(false);//will succeed without an exception
});
System.out.println("result1 present: " + result1.isPresent());
System.out.println("result2 present: " + result2.isPresent());
System.out.println("result2: " + result2.get());
}
public static int doCalculations(boolean throwException) {
boolean failed = throwException;//test throwing an exception
//TODO do some calculations...
int theAnswer = 42;
if (failed) {
throw new IllegalStateException("calculations failed");
}
return theAnswer;
}
The test generates the following output:
logger warning: calculations failed
result1 present: false
result2 present: true
result2: 42
complete example code
import java.util.Optional;
public class ExceptionWrapperUtil {
public static <T> Optional<T> wrappException(SupplierWithException<T> supplierThatThrowsException) {
try {
return Optional.of(supplierThatThrowsException.get());
}
catch (Exception e) {
//logger.warn(e.getMessage()); //TODO add a real logger here
System.err.println("logger warning: " + e.getMessage());
}
return Optional.empty();
};
@FunctionalInterface
public interface SupplierWithException<T> {
public T get() throws Exception;
}
public static void main(String[] args) {
Optional<Integer> result1 = ExceptionWrapperUtil.wrappException(//
//create a SupplierWithException object (as lambda expression, because it's a functional interface)
//when the get() method is called (within the wrappException method) the calculation is started
() -> {
return doCalculations(true);//will throw an exception that is logged
});
Optional<Integer> result2 = ExceptionWrapperUtil.wrappException(() -> {
return doCalculations(false);//will succeed without an exception
});
System.out.println("result1 present: " + result1.isPresent());
System.out.println("result2 present: " + result2.isPresent());
System.out.println("result2: " + result2.get());
}
public static int doCalculations(boolean throwException) {
boolean failed = throwException;//test throwing an exception
//TODO do some calculations...
int theAnswer = 42;
if (failed) {
throw new IllegalStateException("calculations failed");
}
return theAnswer;
}
}