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

Time:10-29

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.

CodePudding user response:

As per Kotlin's doc for runCatching:

Calls the specified function block and returns its encapsulated result if invocation was successful, catching any Throwable exception that was thrown from the block function execution and encapsulating it as a failure.

Even if finally always runs after a try block and also always runs after a runCatching, they do not serve the same purpose.

finally doesn't receive any argument and cannot operate on the values of the try block, while also receives the Result of the runCatching block.

TLDR; .runCatching{}.also{} is a more advanced try{}finally{}

CodePudding user response:

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 confuses whoever will read 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().

  • Related