diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt
index 7d6f69ad694..2a8aceb7cf4 100644
--- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt
+++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/Either.kt
@@ -1368,6 +1368,32 @@ public fun A.left(): Either = Left(this)
public fun A.right(): Either = Right(this)
+/**
+ * Returns the [Right] value or throws an exception created by applying the [onLeft] function to the [Left] value.
+ *
+ * ```kotlin
+ * import arrow.core.Either
+ * import io.kotest.assertions.throwables.shouldThrow
+ * import io.kotest.matchers.shouldBe
+ *
+ * fun test() {
+ * Either.Right(12).getOrElseThrow { RuntimeException("Error: $it") } shouldBe 12
+ * shouldThrow {
+ * Either.Left("error").getOrElseThrow { RuntimeException("Error: $it") }
+ * }.message shouldBe "Error: error"
+ * }
+ * ```
+ *
+ *
+ */
+public inline fun Either.getOrElseThrow(onLeft: (A) -> Throwable): B {
+ contract { callsInPlace(onLeft, InvocationKind.AT_MOST_ONCE) }
+ return when (this) {
+ is Left -> throw onLeft(this.value)
+ is Right -> this.value
+ }
+}
+
public operator fun , B : Comparable> Either.compareTo(other: Either): Int =
fold(
{ a1 -> other.fold({ a2 -> a1.compareTo(a2) }, { -1 }) },
diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt
index 8e570bcec97..29d139437d8 100644
--- a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt
+++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/EitherTest.kt
@@ -130,6 +130,22 @@ class EitherTest {
}
}
+ @Test
+ fun getOrElseThrowOk() = runTest {
+ checkAll(Arb.int(), Arb.string()) { a: Int, b: String ->
+ Right(a).getOrElseThrow { RuntimeException(it.toString()) } shouldBe a
+
+ val exception = try {
+ Left(b).getOrElseThrow { RuntimeException(it) }
+ null // Should not reach here
+ } catch (e: RuntimeException) {
+ e
+ }
+
+ exception?.message shouldBe b
+ }
+ }
+
@Test
fun getOrNullOk() = runTest {
checkAll(Arb.int()) { a: Int ->