The ```public inline fun <Error, A, B> fold(...
# arrow
n
The
Copy code
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
method has the following remark:
This method should never be wrapped in try/catch as it will not throw any unexpected errors
Actually, if the
recover
handler throws an exception it is simply rethrown, so the
catch
handler applies only to
block
, so the following test succeeds:
Copy code
data object DivisionByZero

context(Raise<DivisionByZero>)
private fun div(a: Int, b: Int): Int =
    if (b != 0) {
        a / b
    } else {
        raise(DivisionByZero)
    }

@Test
fun testFoldExceptionHandling() {
    try {
        fold<DivisionByZero, Int, Int>({
            div(1, 0)
        }, {
            throw IllegalStateException("catch", it)
        }, {
            throw IllegalStateException("recover: $it")
        },
            ::identity
        )
        fail()
    } catch (e: Exception) {
        assertEquals("recover: $DivisionByZero", e.message)
    }
}
My questions is: is the documentation stale, or is this an actual semantic bug?
Of course the same applies to
recover()
as well:
Copy code
@Test
fun testRecoverExceptionHandling() {
    try {
        recover<DivisionByZero, Int>({
            div(1, 0)
        }, {
            throw IllegalStateException("recover: $it")
        }, {
            throw IllegalStateException("catch", it)
        })
        fail()
    } catch (e: Exception) {
        assertEquals("recover: $DivisionByZero", e.message)
    }
}
y
Any unexpected errors I guess is the distinction here, but you're right, the docs should be updated to be clearer
👍🏻 1