Erik Huizinga
1 min readMay 7, 2021

--

In general, try to avoid catching all exceptions just for the simplicity of this runCatching construct. Only catch exceptions that you expect and want to handle! On the JVM, you can expect all kinds of system throwables, e.g. out of memory. With 3rd party libs, like coroutines, you can expect even more, like cancellation. Often you do not want to handle these exceptions. Catch only what you expect and want to handle! When I use runCatching, I check for the expected types of the caught throwable. Then I handle those; any others I just rethrow. This preserves throwable transparency.

Arguably, the runCatching API is too powerful in the sense that it invites inappropriate use because it catches everything by default. That has another consequence, which is that developers might start throwing exceptions to communicate normal messages, like error states, just because it's so easy and so 'functional' to do so with our friendly little powertool called runCatching. No!

There are alternatives to throwing, like returning null or materialising errors/error states. Rethrowing is fine, but instantiating throwables yourself often is likely unnecessary (and usually costly too, Google it). It is even against what I would call idiomatic Kotlin. Also see this excellent article about issues with exceptions, how Kotlin is designed around them and why that actually works well: https://elizarov.medium.com/kotlin-and-exceptions-8062f589d07

--

--