A tiny inline function for consise try/catch
In JVM every call can throw an exception. In Java language, we have dedicated declaration that a method is
expected to throw some exception types. But still, some other (Throwable
, Error
, RuntimeException
) exceptions
may still be thrown.
In Kotlin there are no checked exceptions (like, say in C#). Sill, one have to expect any possible exception being thrown from any possible place.
Most cases it’s ok and one should not do anything specific about exceptions. Still, there are other places, where an exception may break code logic. In asynchronous applications (for example with RxJava, Netty, grpc-java) where most of the code is a callback, it may turn out necessary to make sure an exception is not breaking some outer login.
A trivial solution is to use try/catch
. But it makes a code quite ugly when you have several statements to call. It
may look like that
A good think here is that try/catch
is expression in Kotlin, but still it is quite long to use.
In my application, I found that about 80% of such catches were done to
log actual problem and to continue forking further. Meaning handleActionNError()
functions in my case were
calls to a Logger
.
There is now equivalent way in Java to replace this long construction. Of course, it is possible to pass a
lambda expression into a function like catchAll
. But this would change a program and it would add extra
object creation in most of the cases.
One can implement similar catchAll
function in Kotlin too. Thanks to
inline functions
it has no overhead at all.
This is the function I use:
So now I may rewrite the above example in a way consise fashion
Every usage of the function catchAll
is inlined by Kotlin compiler in to a caller method bodies. Kotlin compiler also
inlines the action anonymous function action
too. There is no overhead! Let’s consider the following
example:
The following bytecode is generated out of it. Note. I use IntelliJ IDEA 2017.1 EAP with Kotlin 1.0.6 plugin. The generated bytecode may change with a future version of tools.
As we see the catchAll
function call is inlined. We have println
call as-is, without any anonymous function
wrappers. Any combination of catchAll
calls generates similar bytecode with try/catch
blocks. Once can easily combine
such calls to make a program easier to read on some higher level.
Disclaimer. Checked or unchecked exceptions are meaningful. I’m not trying to promote the idea to catch all possible exceptions in every possible statement. The goal is to show it is possible to create a tiny function that would help to recure a number of similar code snippets and improve readability. It is up to you to decide if an error is OK to ignore or to log without propagation.
comments powered by Disqus