aboutsummaryrefslogtreecommitdiff
path: root/coroutine-utils
diff options
context:
space:
mode:
authorAditya Wasan <adityawasan55@gmail.com>2022-03-23 18:18:06 +0530
committerGitHub <noreply@github.com>2022-03-23 12:48:06 +0000
commit9c9616d04752e5b47966917f8648fdbb62e05ba9 (patch)
tree25ec60c1fcbe1b8e47e387d3c766fbfa06370b95 /coroutine-utils
parentcf3ae17b8461d9c94e38760e582950f7f26da855 (diff)
fix: ignore `CancellationException` in suspend functions (#1794)
* fix: ignore `CancellationException` in suspend functions Signed-off-by: Aditya Wasan <adityawasan55@gmail.com> * build(coroutine-utils): use `api` instead of `implementation` Co-authored-by: Harsh Shandilya <me@msfjarvis.dev> Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
Diffstat (limited to 'coroutine-utils')
-rw-r--r--coroutine-utils/build.gradle.kts1
-rw-r--r--coroutine-utils/src/main/kotlin/dev/msfjarvis/aps/util/coroutines/RunSuspendCatching.kt48
2 files changed, 49 insertions, 0 deletions
diff --git a/coroutine-utils/build.gradle.kts b/coroutine-utils/build.gradle.kts
index 2a20df08..78f1e8c2 100644
--- a/coroutine-utils/build.gradle.kts
+++ b/coroutine-utils/build.gradle.kts
@@ -10,4 +10,5 @@ plugins {
dependencies {
implementation(libs.kotlin.coroutines.core)
implementation(libs.dagger.hilt.core)
+ api(libs.thirdparty.kotlinResult)
}
diff --git a/coroutine-utils/src/main/kotlin/dev/msfjarvis/aps/util/coroutines/RunSuspendCatching.kt b/coroutine-utils/src/main/kotlin/dev/msfjarvis/aps/util/coroutines/RunSuspendCatching.kt
new file mode 100644
index 00000000..7e5b906c
--- /dev/null
+++ b/coroutine-utils/src/main/kotlin/dev/msfjarvis/aps/util/coroutines/RunSuspendCatching.kt
@@ -0,0 +1,48 @@
+@file:OptIn(ExperimentalContracts::class)
+@file:Suppress("RedundantSuspendModifier")
+
+package dev.msfjarvis.aps.util.coroutines
+
+import com.github.michaelbull.result.Err
+import com.github.michaelbull.result.Ok
+import com.github.michaelbull.result.Result
+import kotlin.contracts.ExperimentalContracts
+import kotlin.contracts.InvocationKind
+import kotlin.contracts.contract
+import kotlinx.coroutines.CancellationException
+
+/**
+ * Calls the specified function [block] with [this] value as its receiver and returns its
+ * encapsulated result if invocation was successful, catching any [Throwable] except
+ * [CancellationException] that was thrown from the [block] function execution and encapsulating it
+ * as a failure.
+ */
+public suspend inline fun <V> runSuspendCatching(block: () -> V): Result<V, Throwable> {
+ contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
+
+ return try {
+ Ok(block())
+ } catch (e: Throwable) {
+ if (e is CancellationException) throw e
+ Err(e)
+ }
+}
+
+/**
+ * Calls the specified function [block] with [this] value as its receiver and returns its
+ * encapsulated result if invocation was successful, catching any [Throwable] except
+ * [CancellationException] that was thrown from the [block] function execution and encapsulating it
+ * as a failure.
+ */
+public suspend inline infix fun <T, V> T.runSuspendCatching(
+ block: T.() -> V
+): Result<V, Throwable> {
+ contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
+
+ return try {
+ Ok(block())
+ } catch (e: Throwable) {
+ if (e is CancellationException) throw e
+ Err(e)
+ }
+}