catch

infix fun <Error, A> Effect<Error, A>.catch(catch: suspend Raise<Error>.(throwable: Throwable) -> A): Effect<Error, A>

Catch any unexpected exceptions, and catch them. You can either return a value a new value of A, or short-circuit the effect by raising with a value of Error, or raise an exception into suspend.

import arrow.core.raise.effect
import arrow.core.raise.catch

object User
object Error

val exception = effect<Error, User> { throw RuntimeException("BOOM") } // Exception(BOOM)

val a = exception.catch { error -> error.message?.length ?: -1 } // Success(5)
val b = exception.catch { raise(Error) } // Raise(error)
val c = exception.catch { throw RuntimeException("other-failure") } // Exception(other-failure)

@JvmName(name = "catchReified")
infix inline fun <T : Throwable, Error, A> Effect<Error, A>.catch(crossinline catch: suspend Raise<Error>.(t: T) -> A): Effect<Error, A>

A version of catch that refines the Throwable to T. This is useful for wrapping foreign code, such as database, network calls, etc.

import arrow.core.raise.effect
import arrow.core.raise.catch

object User
object Error

val x = effect<Error, User> {
throw IllegalArgumentException("builder missed args")
}.catch { raise(Error) }

If you don't need an error value when wrapping your foreign code you can use Nothing to fill the type parameter.

val y = effect<Nothing, User> {
throw IllegalArgumentException("builder missed args")
}.catch<IllegalArgumentException, Error, User> { raise(Error) }

Runs the Effect and captures any nonFatalOrThrow exception into Result.


infix fun <Error, A> EagerEffect<Error, A>.catch(catch: Raise<Error>.(throwable: Throwable) -> A): EagerEffect<Error, A>
@JvmName(name = "catchReified")
infix inline fun <T : Throwable, Error, A> EagerEffect<Error, A>.catch(crossinline catch: Raise<Error>.(t: T) -> A): EagerEffect<Error, A>


inline fun <A> catch(block: () -> A, catch: (throwable: Throwable) -> A): A

Allows safely catching exceptions without capturing CancellationException, or fatal exceptions like OutOfMemoryError or VirtualMachineError on the JVM.

fun test() {
catch({ throw RuntimeException("BOOM") }) { _ ->
"fallback"
} shouldBe "fallback"

fun fetchId(): Int = throw RuntimeException("BOOM")

either {
catch({ fetchId() }) { t ->
raise("something went wrong: ${t.message}")
}
} shouldBe Either.Left("something went wrong: BOOM")
}

Alternatively, you can use try { } catch { } blocks with nonFatalOrThrow. This API offers a similar syntax as the top-level catch functions like Either.catch.


@JvmName(name = "catchReified")
inline fun <T : Throwable, A> catch(block: () -> A, catch: (t: T) -> A): A

Allows safely catching exceptions of type T without capturing CancellationException, or fatal exceptions like OutOfMemoryError or VirtualMachineError on the JVM.

fun test() {
catch({ throw RuntimeException("BOOM") }) { _ ->
"fallback"
} shouldBe "fallback"

fun fetchId(): Int = throw RuntimeException("BOOM")

either {
catch({ fetchId() }) { t: RuntimeException ->
raise("something went wrong: ${t.message}")
}
} shouldBe Either.Left("something went wrong: BOOM")
}

Alternatively, you can use try { } catch(e: T) { } blocks. This API offers a similar syntax as the top-level catch functions like Either.catch.