본문 바로가기
개발&프로그래밍

[Kotlin] runCatching + 코루틴 완벽 활용법! 예외 처리까지 깔끔하게

by 재아군 2025. 6. 17.

Kotlin runCatching + 코루틴 완벽 활용법! 예외 처리까지 깔끔하게

 

Kotlin 코루틴과 runCatching을 함께 사용해 비동기 예외 처리도 안전하고 간결하게 만드는 방법을 상세히 소개합니다.

 


 

블로그 글 목차

  1. 왜 runCatching과 코루틴을 함께 써야 할까?
  2. runCatching과 suspend 함수의 관계
  3. async, launch와 runCatching의 조합 예제
  4. runCatching + withContext 패턴
  5. 실무에서 자주 쓰이는 패턴 3가지
  6. runCatching이 실패하는 경우 주의사항
  7. 마무리하며: 실무에서 더 유용한 코틀린 예외 처리

 

왜 runCatching과 코루틴을 함께 써야 할까?

Kotlin에서는 코루틴을 통해 비동기 로직을 간결하게 작성할 수 있습니다. 하지만 비동기 로직에서 예외가 발생하면 어떻게 처리할까요? 바로 runCatching을 코루틴과 함께 사용하면 안정적이고 선언적인 예외 처리가 가능해집니다.


 

runCatching과 suspend 함수의 관계

suspend 함수 내부에서 예외가 발생해도 runCatching으로 감싸면 안전하게 다룰 수 있습니다.

suspend fun fetchData(): String {
    // 예외 발생 가능
    return "데이터 결과"
}

val result = runCatching { fetchData() }

핵심은 runCatching 자체는 일반 함수이지만, 내부에서 suspend 함수를 실행할 수 있다는 점입니다.


 

async, launch와 runCatching의 조합 예제

val job = CoroutineScope(Dispatchers.IO).launch {
    runCatching {
        val data = fetchRemoteData()
        println("성공: $data")
    }.onFailure {
        println("실패: ${it.message}")
    }
}

 

또는 async와 함께:

val deferred = CoroutineScope(Dispatchers.IO).async {
    runCatching {
        fetchRemoteData()
    }
}

val result = deferred.await()
result.onSuccess {
    println("성공: $it")
}.onFailure {
    println("에러: ${it.message}")
}

 

runCatching + withContext 패턴

특히 withContext와 함께 사용할 때 유용합니다.

val result = withContext(Dispatchers.IO) {
    runCatching { fetchFromDatabase() }
}

result.onSuccess {
    println("데이터 불러오기 성공")
}.onFailure {
    println("DB 에러: ${it.localizedMessage}")
}

 

실무에서 자주 쓰이는 패턴 3가지

  1. ViewModel에서 API 호출 처리
viewModelScope.launch {
    val result = runCatching { repository.getUserProfile() }
    _uiState.value = if (result.isSuccess) {
        UiState.Success(result.getOrNull())
    } else {
        UiState.Error(result.exceptionOrNull())
    }
}
  1. retry가 필요한 API 재시도 로직
suspend fun safeApiCall(): Result<String> {
    return runCatching {
        retry(3) { networkApi.getData() }
    }
}
  1. 로그 수집 + 사용자 알림
runCatching {
    riskyOperation()
}.onFailure {
    log.error("오류 발생", it)
    showToast("문제가 발생했습니다. 다시 시도해주세요.")
}

 

runCatching이 실패하는 경우 주의사항

  • CancellationException은 runCatching으로 잡히지 않고 코루틴 전체를 종료시킵니다.
  • 무조건 예외를 처리한다고 해서 프로그램이 항상 안전한 건 아닙니다. onFailure에서 최소한의 복구 로직을 반드시 설계하세요.

 

 

마무리하며

Kotlin의 runCatching과 코루틴은 궁합이 매우 좋습니다.

예외를 구조화하고, 비동기 흐름 속에서도 코드를 간결하게 유지할 수 있는 강력한 도구죠.

 

비동기 로직에 예외 처리가 자꾸 꼬이신다면, 오늘부터 runCatching을 적극 활용해보세요!


 

댓글