Consider the following Kotlin code using flow and catch. What will be printed?
import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking fun main() = runBlocking { flow { emit(1) emit(2) throw RuntimeException("Error in flow") } .catch { e -> emit(-1) } .collect { value -> println(value) } }
The catch operator catches exceptions and can emit fallback values.
The flow emits 1 and 2, then throws an exception. The catch block catches it and emits -1. So the output is 1, 2, -1.
What error will this Kotlin code produce when run?
import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking fun main() = runBlocking { flow { emit(1) throw IllegalStateException("Oops") } .collect { value -> if (value == 1) throw ArithmeticException("Error in collector") println(value) } }
Exceptions thrown inside collect are not caught by catch in the flow.
The flow emits 1, then the collector throws an ArithmeticException when processing 1. This exception is not caught by the flow's catch, so it propagates.
In Kotlin Flow, which operator is designed to catch exceptions thrown inside the flow builder block?
Think about which operator intercepts exceptions during emission.
The catch operator intercepts exceptions thrown inside the flow builder and allows handling or emitting fallback values.
What will this Kotlin program print?
import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking var attempt = 0 fun main() = runBlocking { flow { attempt++ if (attempt < 3) throw Exception("Try again") emit("Success on attempt $attempt") } .retry(2) .catch { e -> emit("Failed after retries") } .collect { println(it) } }
The retry operator retries the flow emission on exceptions.
The flow throws exceptions on attempts 1 and 2, then succeeds on attempt 3. The retry(2) allows two retries, so it succeeds and emits "Success on attempt 3".
Examine this Kotlin code. Why does the catch block not catch the exception?
import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking fun main() = runBlocking { flow { emit(1) emit(2) } .catch { e -> println("Caught: $e") } .collect { value -> if (value == 2) throw RuntimeException("Error in collector") println(value) } }
Consider where exceptions are thrown and where catch applies.
The catch operator only catches exceptions thrown upstream in the flow builder or operators before collect. Exceptions thrown inside collect are outside its scope and propagate normally.