with Cleanup
Runs block and then always runs cleanup inside withContext(NonCancellable), so cleanup is allowed to suspend even when the coroutine is already cancelled.
cleanup runs after block succeeds, throws, or is cancelled. If block failed and cleanup also throws, the exception from block is kept and the cleanup exception is attached with addSuppressed. If only cleanup throws, that exception propagates.
Example:
withCleanup(cleanup = { session.close() }) {
session.send(request)
}Cancellation of block is not swallowed: after cleanup has run, the original CancellationException is rethrown like any other exception from block.
Rule: CANCEL_004 (cleanup in finally that suspends must use NonCancellable). See docs/BEST_PRACTICES_COROUTINES.md.
Requires opting in to ExperimentalStructuredCoroutines.
Return
the value returned by block.
Parameters
suspending cleanup, always executed in a NonCancellable context.
the main work.
See also
Throws
whatever block threw (including CancellationException), or the exception from cleanup when block succeeded.