1

I have code I've written inside an either.eager

return either.eager<MyException, MyResponse> {

    val objList = service.getObjs().bind()
    val obj = objList.find{...} ?: throw MyException.notFoundException()

    someOtherService.doSomethingWith(obj).bind()
}
.fold(
    ...
)

My question is:

Is this the idiomatic way to handle errors within an either.eager? i.e is it ok to throw an exception from inside an eager?

I could create a function to do the find and return an Either there but that isn't exactly the kotlin idiomatic way.

Somaiah Kumbera
  • 7,063
  • 4
  • 43
  • 44

1 Answers1

2

Each EffectScope and EagerEffectScope expose shift, where you can short-circuit to R in this case MyException.

When find returns a Nullable Type you can use ensureNotNull, which uses shift underneath.

return either.eager<MyException, MyResponse> {

    val objList = service.getObjs().bind()
    val obj = ensureNotNull(objList.find{...}) { MyException.notFoundException() }

    someOtherService.doSomethingWith(obj).bind()
}
.fold(
    ...
)
  • Thank you for your quick answer Imran. I tried this, but I get a `estricted suspending functions can only invoke member or extension suspending functions on their restricted coroutine scope` Also, more generally speaking, what if I wanted to short circuit for some other reason, not specifically notNull? – Somaiah Kumbera Jun 03 '22 at 20:42
  • That means one of the functions above is suspended and you would need `either`, instead of `either.eager`. Short circuiting always works with `shift`[here](https://github.com/arrow-kt/arrow/blob/d5edbe2fc337d50ae83a9a60a197f21fdeb5c93c/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EagerEffectScope.kt#L33) or [here](https://github.com/arrow-kt/arrow/blob/d5edbe2fc337d50ae83a9a60a197f21fdeb5c93c/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/continuations/EffectScope.kt#L31), unless I misunderstood your last question. – Imran Malic Settuba Jun 04 '22 at 10:15
  • Arrow core continuations works with the suspension system in Kotlin, that means an EffectScope allows both suspended and non-suspended computations, but EagerEffectScope prohibits suspended functions. That's why you're getting the same compiler error message as if you would run a suspended function in non suspended context. – Imran Malic Settuba Jun 04 '22 at 10:26
  • Thank you Imran. I think I need to upgrade my arrow to get this to work. I'm on 1.1.3 now and its working fine. While the ensureNotNull is a nice way to handle this, is there another more generic way to handle this? – Somaiah Kumbera Nov 10 '22 at 20:29
  • Ignore my last comment. I found the docs and it explains clearly that ensure (and ensureNOtNull) do or do not allow the binding to continue. https://arrow-kt.io/docs/apidocs/arrow-core/arrow.core.computations/-either-effect/ensure.html I think this is the nice generic way I was looking for. Thank you again. – Somaiah Kumbera Nov 10 '22 at 20:34