Satyam Agarwal
09/11/2020, 8:49 PMIO
, and I am now converting it in arrow-fx-coroutines
.
Thing that I am not able to get my head around is how `IO`’s edge of the world conditions is taken care of if i use arrow-fx-coroutines
When using IO
, I was doing like this :
sealed class DomainError : Throwable() {
object NotFound : DomainError()
object NullInIO : DomainError()
override fun fillInStackTrace(): Throwable = this
}
and just before sending response to client, I was doing something like :
fun IO<DomainResponse>.send(): Unit {
return this
.attempt()
.flatMap { response ->
when (response) {
is Either.Left -> { check if it is DomainError and send appropriate response, or else log the unknown error and send generic 500 internal server error }
is Either.Right -> { send 200 ok response }
}
}
.suspendCancellable()
}
By doing something like this I was catching all of the exceptions which wasn’t known to me but were thrown under certain unfortunate scenarios. This kind of approach made me aware of holes in my code, and time to time I went back and fixed them to the point that there are no more surprises.
I hoped that BIO<DomainError, A>
would’ve cleaned up DomainError
sealed class by not extending Throwable, and still covering me like IO<Throwable, A>
, but it is reverted.
How can I do this with Either ? Either.catch
gives Either<Throwable, A>
, and from what I’ve read here, whole point was not to use Throwable
with Either
.Joram Visser
09/11/2020, 9:17 PMhandle
function I mentioned earlier.
fun (suspend () -> Either<DomainError, DomainResponse>).send(): Unit =
handle(
logic = this,
ifSuccess = { a -> /* send 200 ok response */},
ifDomainError = { e -> /* send appropriate response for DomainError */},
ifSystemFailure = { throwable -> /* log the unknown error and send generic 500 internal server error */}
)
Joram Visser
09/11/2020, 9:18 PMraulraja
09/11/2020, 10:55 PMraulraja
09/11/2020, 10:56 PMraulraja
09/12/2020, 6:30 AM