I use the Java 8 Stream API, and as we know, it does not support checked exceptions inside any functional interface inside java.util.function.
I usually have to use a method with checked exceptions inside stream operations, and I wrote a CheckedFunction decoder to use inside these operations:
import java.util.function.BiFunction; import java.util.function.Function; public interface CheckedFunction<T, R, E extends Throwable> { R apply(T t) throws E; static <T, R, CE extends Throwable, UCE extends RuntimeException> Function<T, R> checked( CheckedFunction<T, R, CE> checked, Function<CE, UCE> exceptionHandler) { return (t) -> { try { return checked.apply(t); } catch (RuntimeException | Error e) { throw e; } catch (Throwable e) {
so I can use it in such cases:
entities.stream() .map(checked((entity) -> someResultChecked(entity), // throws IOException (entity, e) -> { // e is of type IOException log.error("exception during checked method of " + entity, e); return new UncheckedIOException(e); })) .map(checked((entity) -> saveToDb(entity), // throws SQLException (entity, e) -> { // e is of type SQLException log.error("exception during saving " + entity, e); return new UncheckedSQLException(e); })) .map(checked((entity) -> manyExceptionMethod(entity), // throws IOException, SQLException (entity, e) -> { // e is of type Throwable return new RuntimeException(e); }))
It will package any thrown exception in unchecked, but I know that if a method throws more than one exception, it will remove Throwable, I will use it in simple cases.
Is this a good idea, or can I run into hidden obstacles?
UPDATED: Reusing RuntimeExceptions.
I also found a clearer solution in jOOL with InterruptedException handling that could cause inconsistent behavior if ignored: https://github.com/jOOQ/jOOL/blob/master/src/main/java/org/jooq/lambda/ Unchecked.java