Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Kotlin's runCatching..also equivalent to try..finally?

Tags:

kotlin

I want to run cleanup code after a certain block of code completes, regardless of exceptions. This is not a closeable resource and I cannot use try-with-resources (or Kotlin's use). In Java, I could do the following:

try {
  // ... Run some code
} catch(Exception ex) {
  // ... Handle exception 
} finally {
  // ... Cleanup code
}

Is the following Kotlin code equivalent?

runCatching {
  // ... Run some code
}.also {
  // ... Cleanup code
}.onFailure {
  // ... Handle exception
}

Edit: added boilerplate exception handling - my concern is with ensuring the cleanup code runs, and maintainability.

like image 379
Itay Polack-Gadassi Avatar asked Sep 02 '25 06:09

Itay Polack-Gadassi


2 Answers

There is one important difference, where the code inside runCatching contains an early return. A finally block will be executed even after a return, whereas also has no such magic.

This code, when run, will print nothing:

fun test1()
    runCatching {
        return
    }.also {
        println("test1")
    }
}

This code, when run, will print "test2":

fun test2() {
    try {
        return
    } finally {
        println("test2")
    }
}
like image 59
Sam Avatar answered Sep 04 '25 18:09

Sam


There is one big difference between both code samples. try...finally propagates exceptions while runCatching().also() catches/consumes them. To make it similar you would have to throw the result at the end:

runCatching {
  // ... Run some code
}.also {
  // ... Cleanup code
}.getOrThrow()

But still, it is not really 1:1 equivalent. It catches all exceptions just to rethrow them. For this reason, it is probably less performant than simple try...finally.

Also, I think this is less clear for the reader. try...finally is a standard way of dealing with exceptions. By using runCatching() just to immediately rethrow, you actually confuse people reading this code later.

Your question sounded a little like you believed Kotlin does not have try...finally and you need to search for alternatives. If this is the case, then of course Kotlin has try...finally and I think you should use it instead of runCatching().

like image 30
broot Avatar answered Sep 04 '25 18:09

broot



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!