catch
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)
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.
Allows safely catching exceptions without capturing CancellationException, or fatal exceptions like OutOfMemoryError
or VirtualMachineError
on the JVM.
fun test() {
catch({ throw RuntimeException("BOOM") }) { t ->
"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.
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") }) { t ->
"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.