-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Why don't you use generic exception inside CheckedFunction? #237
Comments
Thank you very much for your suggestion. There's an existing Of course, as a workaround, you could also write a small utility: Unchecked.function(Test::throwsSQLException, wrap(SQLException.class, UncheckedSQLException::new)); with static <X extends Throwable> Consumer<Throwable> wrap(Class<X> x, Function<? super X, ? extends RuntimeException> f) {
return t -> {
if (x.isInstance(t))
return f.apply((X) t);
else
return new RuntimeException(t);
};
} |
Thanks for the answer, I think it would be better if I don't lose existing handling of InterruptException: static <X extends Throwable> Consumer<Throwable> wrap(Class<X> x, Function<? super X, ? extends RuntimeException> f) {
return t -> {
if (x.isInstance(t))
throw f.apply((X) t);
else
Unchecked.THROWABLE_TO_RUNTIME_EXCEPTION.accept(t);
};
} Thanks a lot. |
Indeed, your suggestion is better. This will also include any future improvement that we add to |
Also keep in mind that using non-generic exception does not allow accepting function permitted for specific exception (please omit the resource closing). private static ResultSet executeOnAllDatasources(CheckedFunction<Connection, ResultSet> function) throws SQLException {
SQLException last = null;
for (DataSource dataSource : dataSources) {
try {
return function.apply(dataSource.getConnection());
}
catch (SQLException e) {
last = e;
}
catch (Throwable t) {
// correct handling of unchecked exceptions should be here, but who cares...
throw new RuntimeException(t);
}
}
throw last;
} try {
executeOnAllDatasources(connection -> {
return connection.prepareStatement("SELECT * FROM table").executeQuery();
});
}
catch (SQLException e) {
throw new ServiceException("operation failed on all data sources");
} in case of adding new checked exception inside function user won't see the effects of it, but if you are using generic exception compiler will show error: private static ResultSet executeOnAllDatasources(CheckedFunction<Connection, ResultSet, SQLException> function) throws SQLException {
SQLException last = null;
for (DataSource dataSource : dataSources) {
try {
return function.apply(dataSource.getConnection());
}
catch (SQLException e) {
last = e;
}
// no re-throwing Error or RuntimeException, missing InterruptException isn't possible due to restriction
}
throw last;
} But as you said if there are strong limitations (I know only about catching generic exceptions) or some other issues with generic exception it's bad idea. |
OK, I can see your point. Indeed, such a change does seem to suggest a much easier handling of wrapping such blocks. Now, there are only two problems left:
|
Any use of CheckedFunction requires to use instanceof, but in most cases compiler would do it for us.
Look at the little example:
If we want convert throwing SQLException function to unchecked we should write a lot meaningless code using Unchecked:
but using function with generic exception:
we can optimize two of three cases.
If methods throws single checked exception compiler will infer type of this exception so we can just write
When function throws more than one checked exception compilers can't put two exceptions and requires Throwable to be handled:
Also using transforming function protects us from checking than exception was thown and user actually understands what we exactly want.
The text was updated successfully, but these errors were encountered: