개발일기

Kotlin Coroutine 예외 처리 패턴

뱅우 2025. 8. 15. 11:43
반응형
Kotlin Coroutine 예외 처리 패턴

Kotlin Coroutine 예외 처리 패턴

Kotlin Coroutine을 사용할 때 예외 처리는 비동기 작업의 안정성을 확보하는 핵심 요소입니다. Coroutine의 예외 처리는 일반적인 try-catch와는 다르게 CoroutineScope, Job, SupervisorJob 등에 따라 동작 방식이 달라집니다.

1. 기본 예외 처리

Coroutine 내에서는 try-catch를 사용해 예외를 잡을 수 있습니다.

GlobalScope.launch {
    try {
        throw Exception("에러 발생!")
    } catch (e: Exception) {
        println("예외 처리: ${e.message}")
    }
}

2. CoroutineExceptionHandler 사용

전역적으로 예외를 처리하고 싶다면 CoroutineExceptionHandler를 사용합니다.

val handler = CoroutineExceptionHandler { _, exception ->
    println("예외 처리: ${exception.message}")
}

GlobalScope.launch(handler) {
    throw Exception("에러 발생!")
}

3. SupervisorJob을 이용한 독립적 예외 처리

일반적으로 하나의 자식 Coroutine이 실패하면 부모 Coroutine이 취소되지만, SupervisorJob을 사용하면 다른 자식 Coroutine에 영향을 주지 않습니다.

val supervisor = SupervisorJob()

CoroutineScope(Dispatchers.Default + supervisor).launch {
    launch {
        throw Exception("첫 번째 실패")
    }
    launch {
        delay(1000)
        println("두 번째는 정상 실행")
    }
}

4. async와 예외 처리

async는 예외가 지연 전파되므로 await()를 호출할 때 예외가 발생합니다.

val deferred = GlobalScope.async {
    throw Exception("async 에러")
}

try {
    deferred.await()
} catch (e: Exception) {
    println("예외 처리: ${e.message}")
}

5. 예외 처리 시 주의사항

  • launch: 예외가 발생하면 즉시 전파
  • async: await() 호출 시 예외 전파
  • SupervisorJob: 다른 자식 Coroutine에 영향 최소화
  • CoroutineExceptionHandler: 전역 처리 시 유용

결론: Coroutine 예외 처리는 단순히 try-catch만으로 해결되지 않으며, 상황에 따라 CoroutineExceptionHandler, SupervisorJob 등을 적절히 조합하는 것이 중요합니다.

반응형