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()
.