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..ac775b1586d 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
@@ -1344,6 +1344,32 @@ public inline infix fun Either.getOrElse(default: (A) -> B): B {
}
}
+/**
+ * Returns the right value [B] of this [Either],
+ * or throws an exception produced by applying the [onLeft] function to the left value [A].
+ *
+ * ```kotlin
+ * import arrow.core.Either
+ * import arrow.core.getOrElseThrow
+ * 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
+ }
+}
+
/**
* Returns the value from this [Right] or [Left].
*
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..fa6fae53ff1 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
@@ -129,6 +129,21 @@ class EitherTest {
Left(a).getOrElse { b } shouldBe b
}
}
+
+ @Test
+ fun getOrElseThrowOk() = runTest {
+ checkAll(Arb.int()) { a: Int ->
+ Right(a).getOrElseThrow { RuntimeException("Error: $it") } shouldBe a
+
+ val left: Either = Left("error")
+ try {
+ left.getOrElseThrow { RuntimeException("Error: $it") }
+ fail("Should have thrown an exception")
+ } catch (e: RuntimeException) {
+ e.message shouldBe "Error: error"
+ }
+ }
+ }
@Test
fun getOrNullOk() = runTest {