Flow
수집(collect
)은 방출(emit
)하는 곳이나 연산자 안의 코드가 예외를 발생시키는 경우 예외와 함께 완료될 수 있음.
collect
)는 예외를 처리하기 위해 try/catch
블록을 사용할 수 있음.emit
)되지 않음.import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking<Unit> {
try {
simple().collect { value ->
println(value)
check(value <= 1) { "Collected $value" }
}
} catch (e: Throwable) {
println("Caught $e")
}
}
fun simple(): Flow<Int> = flow {
for (i in 1..3) {
println("Emitting $i")
emit(i) // emit next value
}
}
실행결과
Emitting 1
1
Emitting 2
2
Caught java.lang.IllegalStateException: Collected 2
fun main() = runBlocking<Unit> {
try {
simple().collect { value -> println(value) }
} catch (e: Throwable) {
println("Caught $e")
}
}
fun simple(): Flow<String> = flow {
for (i in 1..3) {
println("Emitting $i")
emit(i)
}
}.map { value ->
println("Map $value")
check(value <= 1) { "Crashed on $value" }
"string $value"
}
실행결과
Emitting 1
Map 1
string 1
Emitting 2
Map 2
Caught java.lang.IllegalStateException: Crashed on 2
Flow
는 예외에 투명해야 함try/catch
블록 내부에서 flow { .. }
빌더의 값을 방출하는 것은 예외 투명성을 위반하는 것임.try/catch
를 사용해 예외를 잡아낼 수 있음.catch
연산자를 사용해 예외 투명성을 유지시키고 예외 처리를 캡슐화 할 수 있음.
catch
연산자의 코드 블록은 예외를 분석하고, 잡은 예외에 따라 다른 방식으로 대응할 수 있음.fun main() = runBlocking<Unit> {
simple()
.catch { e -> emit("Caught $e") } // emit on exception
.collect { value -> println(value) }
}
실행결과
Emitting 1
string 1
Emitting 2
Caught java.lang.IllegalStateException: Crashed on 2
throw
를 통해서 다시 re-throw 될 수 있음.catch
의 코드 블록에서 emit
을 사용해 예외를 방출로 바꿀 수 있음.