@elizarov Can sealed classes play well with flows? Let me explain:
Imagine we want to create a flow which is transparent regarding exceptions. We have this sealed class to represent either a success of failure:
sealed class Result
data class Success(val image: Image) : Result()
object Error : Result()
class Image
And we have a suspending function to fetch an Image, which can throw an exception:
suspend fun fetchImage(url: String): Image {
// Returns either an Image instance or throws an exception
}
So we wrap this nasty function in another function which we'll use in our flows:
suspend fun fetchResult(url: String): Result {
return try {
val image = fetchImage(url)
Success(image)
} catch (e: IOException) {
Error
}
}
Finally, we can use it:
val urlFlow = flowOf("url1, url2", "retry")
val resultFlow = urlFlow.map { url -> fetchResult(url) }
So far, so good.
However, out of curiosity, I tried to re-write the same flow above using the catch operator:
val resultFlow: Flow<Result> = urlFlow.map { url ->
val image = fetchImage(url)
Success(image)
}.catch { e ->
emit(Error)
}
This code does not compile. I try to emit an Error from catch (even if it's a valid Result instance). The compiler says: "Type mismatch, required Success".
I know that it's because the inferred type of the upstream flow before catch is Flow<Success>.
But in my humble opinion, we should be able to write some similar logic with a flow of some super type, and FlowCollectors being able to emit subclasses of the sealed class.
Am I missing something?