I actually enjoy the container types and callback errors. The wrapper type Mono<T> acts like a monad of type Promise<Either<T | Error>>. This completely isolates a computation from the rest of the code and puts all of the error handling in one place.
I despise side effects as well as try/catch error handling so these are an especially welcome improvement to java/kotlin.
I don't have much experience with coroutines/flow so I can't actually compare the two approaches but this is my experience with the reactor library. Its unlikely that I will get a chance to continue using Kotlin in the near future but next time I do use Kotlin I will definitely try the coroutine approach and see how it compares.
Basically, with co-routines you lose the need for all the container types like Mono, Flux, etc. and replace them with simple suspend functions. This makes code a lot more readable, easier to test, and reason about.
Instead of callbacks for errors, you can rely on the normal try/catch. Any uncaught exception causes the co routine and co routine scope to fail and cancel in a controlled way. The Flow API allows you to do reactive style processing. It also handles back pressure and a few other things.
Basically fully reactive code written using this is structurally very similar to the normal blocking version of the code.