Skip to content

Instantly share code, notes, and snippets.

@marcellogalhardo
Created February 3, 2023 16:58
Show Gist options
  • Save marcellogalhardo/07215b1a82b46bf2d946f47951fb8d36 to your computer and use it in GitHub Desktop.
Save marcellogalhardo/07215b1a82b46bf2d946f47951fb8d36 to your computer and use it in GitHub Desktop.
Handle exceptions like a pro with Coroutines!
package coroutines
/**
* 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.
*
* Unlike [runCatching], [suspendRunCatching] does not break structured concurrency by rethrowing
* any [CancellationException].
*
* **Heads-up:** [TimeoutCancellationException] extends [CancellationException] but catching it does
* not breaks structured concurrency and therefore, will not be rethrown. Therefore, you can use
* [suspendRunCatching] with [withTimeout], and handle any timeout gracefully.
*
* @see <a href="https://github.com/Kotlin/kotlinx.coroutines/issues/1814">link</a>
*/
suspend inline fun <T> suspendRunCatching(crossinline block: suspend () -> T): Result<T> =
try {
Result.success(block())
} catch (e: Throwable) {
currentCoroutineContext().ensureActive()
Result.failure(e)
}
/**
* 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.
*
* Unlike [runCatching], [suspendRunCatching] does not break structured concurrency by rethrowing
* any [CancellationException].
*
* **Heads-up:** [TimeoutCancellationException] extends [CancellationException] but catching it does
* not breaks structured concurrency and therefore, will not be rethrown. Therefore, you can use
* [suspendRunCatching] with [withTimeout], and handle any timeout gracefully.
*
* @see <a href="https://github.com/Kotlin/kotlinx.coroutines/issues/1814">link</a>
*/
suspend inline fun <T, R> T.suspendRunCatching(crossinline block: suspend T.() -> R): Result<R> =
// Overload with a `this` receiver, matches with `kotlin.runCatching` functions.
// Qualified name needs to be used to avoid a recursive call.
coroutines.suspendRunCatching { block(this) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment