I am using the jdbi library like so:
try {
return jdbi.withHandle(handle -> handle
.createQuery("...")
.mapTo(String.class)
.one());
} catch (final JdbiException e) {
if (DatabaseExceptionChecker.isTransientException(e)) {
throw new MyCustomException("Transient database exception", e);
} else {
throw e;
}
}
This try catch pattern is repeated a few times, with various different queries passed to the jdbi.withHandle method. Another example:
try {
return jdbi.withHandle(handle -> handle
.createUpdate("...")
.execute());
} catch (final JdbiException e) {
if (DatabaseExceptionChecker.isTransientException(e)) {
throw new MyCustomException("Transient database exception", e);
} else {
throw e;
}
}
The jdbi.withHandle method has this signature:
public <R, X extends Exception> R withHandle(HandleCallback<R, X> callback) throws X {
I am trying to find a way to reduce the duplication around the try-catch, so that I can use something like this instead:
handleTransientExceptions(() -> jdbi.withHandle(handle -> handle
.createQuery("...")
.mapTo(String.class)
.one())
}
i.e. the handleTransientExceptions function would contain the try-catch boilderplate.
I've begun with the following:
@FunctionalInterface
private interface JdbiCall
{
public <R, X extends Exception> R call() throws X;
}
public <R, X extends Exception> R handleTransientExceptions(final JdbiCall jdbiCall) throws MyCustomException
{
try {
return jdbiCall.call();
} catch (final JdbiException e) {
if (DatabaseExceptionChecker.isTransientException(e)) {
throw new MyCustomException("Transient database exception", e);
} else {
throw e;
}
}
}
however, when I try to call it like this:
return handleTransientExceptions(() -> jdbi.withHandle(handle -> handle
.createQuery("...")
.mapTo(String.class)
.one())
}
I get the error:
reason: cannot infer type-variable(s) R,X
(argument mismatch; invalid functional descriptor for lambda expression
method <R,X>()R in interface com.acmecorp.MyService.JdbiCall is generic)