https://dalinaum.github.io/coroutines-example/14
try-catch 식을 이용
catch() 연산자를 이용해 업스트림에서만 예외처리
수집기 측에서 예외처리하기
예외는 collect을 하는 수집기 측에서도
try-catch 식을 이용해 할 수 있습니다.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun simple(): Flow<Int> = flow {
for (i in 1..3) {
println("Emitting $i")
emit(i) // emit next value
}
}
fun main() = runBlocking<Unit> {
try {
simple().collect { value ->
println(value)
check(value <= 1) { "Collected $value" }
}
} catch (e: Throwable) {
println("Caught $e")
}
}
check(value <= 1) { "Collected $value" } // 여기서 예외가 발생
모든 예외는 처리가능
어느 곳에서 발생한 예외라도 처리가 가능합니다.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun simple(): Flow<String> =
flow {
for (i in 1..3) {
println("Emitting $i")
emit(i) // emit next value
}
}
.map { value ->
check(value <= 1) { "Crashed on $value" }
"string $value"
}
fun main() = runBlocking<Unit> {
try {
simple().collect { value -> println(value) }
} catch (e: Throwable) {
println("Caught $e")
}
}
.map { value ->
check(value <= 1) { "Crashed on $value" }
"string $value"
}
flow 코드 내에서 예외가 나도 잡을수 있다.
예외 투명성 (권장 )
빌더 코드 블록 내에서 예외를 처리하는 것은 예외 투명성을 어기는 것입니다.
( 플로우 내부에서 예외 처리시, 밖에서는 예외가 발생했는지 알수 없다. )
플로우에서는 catch 연산자를 이용하는 것을 권합니다.
catch 블록에서 예외를 새로운 데이터로 만들어 emit을 하거나,
다시 예외를 던지거나, 로그를 남길 수 있습니다.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun simple(): Flow<String> =
flow {
for (i in 1..3) {
println("Emitting $i")
emit(i) // emit next value
}
}
.map { value ->
check(value <= 1) { "Crashed on $value" }
"string $value"
}
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
.catch { e -> emit("Caught $e") } // emit on exception
catch 투명성
catch 연산자는 업스트림(catch 연산자를 쓰기 전의 코드)에만 영향을 미치고
다운스트림에는 영향을 미치지 않습니다. 이를 catch 투명성이라 합니다.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun simple(): Flow<Int> = flow {
for (i in 1..3) {
println("Emitting $i")
emit(i)
}
}
fun main() = runBlocking<Unit> {
simple()
.catch { e -> println("Caught $e") } // does not catch downstream exceptions
.collect { value ->
check(value <= 1) { "Collected $value" }
println(value)
}
}
실행결과
Emitting 1
1
Emitting 2
Exception in thread "main" java.lang.IllegalStateException: Collected 2
at FileKt$main$1$2.emit (File.kt:15)
at FileKt$main$1$2.emit (File.kt:14)
at kotlinx.coroutines.flow.FlowKt__ErrorsKt$catchImpl$2.emit (Errors.kt:158)
.catch { e -> println("Caught $e") } // simple() 에서 발생하는 예외만 다룰수 있음.
.collect { value -> // 여기는 다운 스트림이기때문에 예외를 처리할 수 없다.
check(value <= 1) { "Collected $value" }
println(value)
}
'Android 공부 > Coroutine' 카테고리의 다른 글
[XX캠퍼스] 16.Kotlin Coroutines & Flow ( 런칭 ) (0) | 2022.07.27 |
---|---|
[XX캠퍼스] 15.Kotlin Coroutines & Flow ( 완료 처리하기 ) (0) | 2022.07.27 |
[XX캠퍼스] 13.Kotlin Coroutines & Flow ( 플래트닝 ) (0) | 2022.07.27 |
[XX캠퍼스] 12.Kotlin Coroutines & Flow ( Flow 결합하기 ) (0) | 2022.07.26 |
[XX캠퍼스] 11.Kotlin Coroutines & Flow ( Flow 버퍼링 ) (0) | 2022.07.26 |