I faced that ZIO.map invokes private ZIO.succeedNow which seems will fail running fiber without any chance of handle error
Here is an example:
private val program: ZIO[Any, Throwable, Int] = for {
_ <- ZIO.succeed(println("Start"))
} yield 1 / 0
override def run: ZIO[Any, Any, Unit] = program
.catchAll(e => ZIO.succeed(println(e.getMessage))) *>
ZIO.succeed(println("DONE"))
The output will never print "DONE" in console
The same behavior observed when I'll change the val program to:
private val program: ZIO[Any, Throwable, Int] = for {
_ <- ZIO.succeed(println("Start"))
r <- ZIO.succeed(1 / 0)
} yield r
But when I'm excluding invocation of succeed() everything works fine and I'm getting "DONE" in console
This snippet bellow works as expected
private val program: ZIO[Any, Throwable, Int] = for {
_ <- ZIO.succeed(println("Start"))
r <- ZIO.from(1 / 0)
} yield r
And finally catchAll is invoked
The question is why ZIO.map suppose that passed function should not be failed, and why if it fails I have no chance to handle this error?
In your first example, as you said, you're using
ZIO#map()which semantic/contract is to be used with a function that do not raise exceptions.If you break this intended usage, you get a defect (read more about it) which as you noticed is not caught by
catchAllbut would be usingcatchAllDefect(read more about it).In your second example, the result is the same because this time you break the intended usage of
ZIO.succeed()by giving it a non successful value.