Improve `finally` block exception handling
some-java-user-99206970363698485155 at vodafonemail.de
some-java-user-99206970363698485155 at vodafonemail.de
Sun Apr 17 19:43:14 UTC 2022
Hello,
are there any plans to improve exception handling in combination with `finally` blocks?
Currently, when a `finally` block does not complete normally, the original exception is
silently discarded (as described in the JLS). This behavior is error-prone, not obvious
at all, and has been criticized in the past a lot. An example for this is https://stackoverflow.com/q/48088
and the linked posts there.
While javac warns you about this issue when using `-Xlint:finally`, it is only a warning
and not even enabled by default.
Are there any plans to forbid usage of `break`, `continue`, `yield` and `return` in
`finally` blocks?
Switch expressions have already set a precedent for this by not allowing to leave the
switch expression by something other than a `throw` or `yield` statement, trying to use
for example a `return` statement causes a compilation error.
Similarly for `throw` and any implicitly thrown exceptions, is there a plan to at least
add the original exception as suppressed one to the newly thrown?
Of course one could argue that the same applies to `catch` clauses whose body accidentally
causes an exception which discards the caught one. However the main difference is that
there, only a specific exception type is caught (and discarded), whereas for `finally`
exceptions of _any_ type are discarded. It could also be argued that adding suppressed
exceptions decreases performance or causes memory leaks, but one the other hand
this behavior was explicitly included try-with-resources statements, most likely because the
value this adds was considered more important than any performance issues this
might cause.
Also, it is important to keep in mind that this affects _all_ Throwable types, including
VM errors which you really should not catch, and which due to a `finally` block might
silently be discarded. Most, if not all, code in which a `finally` does not complete
normally does not seem to consider this.
This is also not a theoretical problem; this issue exists in multiple open source projects,
potentially even in the JDK itself.
Often the code can be rewritten by either moving the complete code or parts of it
outside of the `finally` block, or by introducing a local variable to hold the result and
to return that after the `finally` block.
What do you think about this topic?
Is backward compatibility a concern? If so, can you provide an example where using such
a pattern provides any notable advantages which justify the potential loss of thrown
VM errors or exceptions.
Kind regards
More information about the core-libs-dev
mailing list