Skip to content

Commit

Permalink
Revert foldUnsafe
Browse files Browse the repository at this point in the history
  • Loading branch information
nomisRev committed Mar 18, 2024
1 parent 4cd0947 commit 4bd8694
Show file tree
Hide file tree
Showing 2 changed files with 1 addition and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,44 +123,13 @@ public inline fun <Error, A, B> fold(
* This method should never be wrapped in `try`/`catch` as it will not throw any unexpected errors,
* it will only result in [CancellationException], or fatal exceptions such as `OutOfMemoryError`.
*/
@OptIn(DelicateRaiseApi::class)
@JvmName("_fold")
public inline fun <Error, A, B> fold(
@BuilderInference block: Raise<Error>.() -> A,
catch: (throwable: Throwable) -> B,
recover: (error: Error) -> B,
transform: (value: A) -> B,
): B {
contract {
callsInPlace(catch, AT_MOST_ONCE)
callsInPlace(recover, AT_MOST_ONCE)
callsInPlace(transform, AT_MOST_ONCE)
}
return foldUnsafe(block, catch, recover) {
if (it is Function<*> || it is Lazy<*> || it is Sequence<*>)
throw IllegalStateException(
"""
Returning a lazy computation or closure from 'fold' breaks the context scope, and may lead to leaked exceptions on later execution.
Make sure all calls to 'raise' and 'bind' occur within the lifecycle of nullable { }, either { } or similar builders.
See Arrow documentation on 'Typed errors' for further information.
""".trimIndent()
)
transform(it)
}
}

/**
* Similar to [fold], but does *not* check for
* potential lazy return types which break the
* [Raise] context barrier.
*/
@JvmName("_foldUnsafe")
@OptIn(DelicateRaiseApi::class)
public inline fun <Error, A, B> foldUnsafe(
@BuilderInference block: Raise<Error>.() -> A,
catch: (throwable: Throwable) -> B,
recover: (error: Error) -> B,
transform: (value: A) -> B,
): B {
contract {
callsInPlace(catch, AT_MOST_ONCE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,4 @@ class NullableSpec : StringSpec({
one + two
} shouldBe 3
}

"Detects potential leaked exceptions" {
shouldThrow<IllegalStateException> {
nullable { lazy { raise(null) } }
}
}

"Unsafe leakage of exceptions" {
val l: Lazy<Int> = foldUnsafe<String, Lazy<Int>, Lazy<Int>?>(
{ lazy { raise("problem") } }, { throw it }, { null }, { it }
).shouldNotBeNull()
shouldThrow<IllegalStateException> {
l.value
}
}
})

0 comments on commit 4bd8694

Please sign in to comment.