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.
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")
}
}
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()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With