개발일기

안드로이드 에러 처리 및 UI 피드백 전략

뱅우 2025. 9. 10. 09:37
반응형
안드로이드 에러 처리 및 UI 피드백 전략

네트워크 기반 앱 개발에서 에러 처리는 사용자 경험을 좌우하는 중요한 요소입니다. 단순히 Toast로 에러를 띄우는 방식은 사용자에게 불친절하고, 유지보수도 어렵습니다. 이번 글에서는 일관된 에러 처리 방식UI 피드백 전략을 소개합니다.


1. 에러 처리의 기본 원칙

  • 에러를 숨기지 않고 사용자에게 알린다
  • 개발자용 로그와 사용자 피드백을 분리
  • 일관된 구조로 에러를 다룬다 (ex: sealed class)

2. 에러 상태를 UiState에 포함하기

앞선 글에서 사용한 UiState 패턴을 확장하여 에러 상태를 처리합니다.

sealed class UiState<out T> {
    object Loading : UiState<Nothing>()
    data class Success<T>(val data: T) : UiState<T>()
    data class Error(val message: String, val code: Int? = null) : UiState<Nothing>()
}

이렇게 하면 에러 메시지와 상태 코드를 함께 관리할 수 있습니다.


3. ViewModel에서 에러 변환

Retrofit, OkHttp 예외를 UiState.Error로 변환하여 UI에서 일관적으로 처리하도록 합니다.

viewModelScope.launch {
    try {
        val user = repository.getUser()
        _uiState.value = UiState.Success(user)
    } catch (e: HttpException) {
        _uiState.value = UiState.Error("서버 오류 발생", e.code())
    } catch (e: IOException) {
        _uiState.value = UiState.Error("네트워크 연결 실패")
    } catch (e: Exception) {
        _uiState.value = UiState.Error("알 수 없는 오류")
    }
}

4. Compose에서 에러 UI 표현

UI에서는 상태별 UI 분기를 통해 사용자에게 적절한 피드백을 제공합니다.

@Composable
fun UserScreen(uiState: UiState<User>) {
    when (uiState) {
        is UiState.Loading -> CircularProgressIndicator()
        is UiState.Success -> Text("Hello, ${uiState.data.name}")
        is UiState.Error -> ErrorScreen(message = uiState.message)
    }
}

@Composable
fun ErrorScreen(message: String) {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = message, color = Color.Red)
        Button(onClick = { /* 재시도 로직 */ }) {
            Text("다시 시도")
        }
    }
}

5. 에러 처리 전략 정리

  1. 에러 상태를 UiState로 관리
  2. ViewModel에서 예외를 변환하고 UI는 결과만 관찰
  3. 에러 화면을 공통 컴포넌트화하여 재사용성 확보

6. 결론

에러 처리를 체계적으로 설계하면 사용자에게는 명확한 피드백을, 개발자에게는 유지보수 편의성을 제공합니다. 안드로이드 Compose와 ViewModel 조합을 활용하면 이러한 전략을 손쉽게 적용할 수 있습니다.

다음 글 예고: 다음 글에서는 네트워크 + 로컬 캐싱 전략 (Room + Flow)을 다뤄보겠습니다.


반응형