IssueRaiser

Provide a `runCatching` that does not handle a `CancellationException` but re-throws it instead.

### Problem Description The Kotlin StdLib contains a function named `runCatching`. It tries the provided lambda and catches any `Throwable` that is not caught or thrown by the lambda. However, using `runCatching` in Coroutines can have a somewhat hidden (and unexpected) side-effect of it catching `CancellationException`s and not re-throwing them. This could interfere with the Coroutines' Structured Concurrency, with its cancellation handling. ### Possible Solution E.g. create a new function in kotlinx.coroutines that looks something like this (not sure about the name 😄): ``` public inline suspend fun <R> runSuspendCatching(block: () -> R): Result<R> { return try { Result.success(block()) } catch(c: CancellationException) { throw c } catch (e: Throwable) { Result.failure(e) } } ``` The `runSuspendCatching` will catch any exception and wrap it in a `Result`, except for `CancellationException`s that will be re-thrown instead. This will prevent unwanted interference with the cancellation handling of Coroutines. ### Notes - The `suspend` keyword is added to prevent this new function from being called in regular non-suspending/blocking code. - When code calls the StdLib's `runCatching` in a Coroutine/suspendable-context, a lint warning should warn the developer that handling cancellations may be compromised and `runSuspendCatching` should be used instead.

Posted by Anton-Spaans-Intrepid on Feb 18, 2020, 9:36 PM

Tags

Related issues

Raise real-world problems, find people facing the same issue, and discuss solutions.3,500 issues0 comments

github (Software)

Provide a `runCatching` that does not handle a `CancellationException` but re-throws it instead.

Anton-Spaans-IntrepidFeb 18, 2020, 9:36 PM

### Problem Description The Kotlin StdLib contains a function named `runCatching`. It tries the provided lambda and catches any `Throwable` that is not caught or thrown by the lambda. However, using `runCatching` in Coroutines can have a somewhat hidden (and unexpected) side-effect of it catching `CancellationException`s and not re-throwing them. This could interfere with the Coroutines' Structured Concurrency, with its cancellation handling. ### Possible Solution E.g. create a new function in kotlinx.coroutines that looks something like this (not sure about the name 😄): ``` public inline suspend fun <R> runSuspendCatching(block: () -> R): Result<R> { return try { Result.success(block()) } catch(c: CancellationException) { throw c } catch (e: Throwable) { Result.failure(e) } } ``` The `runSuspendCatching` will catch any exception and wrap it in a `Result`, except for `CancellationException`s that will be re-thrown instead. This will prevent unwanted interference with the cancellation handling of Coroutines. ### Notes - The `suspend` keyword is added to prevent this new function from being called in regular non-suspending/blocking code. - When code calls the StdLib's `runCatching` in a Coroutine/suspendable-context, a lint warning should warn the developer that handling cancellations may be compromised and `runSuspendCatching` should be used instead.

Comments (0)

No comments yet. Start the discussion.

Comment on this issue