가정
- 멀티 모듈과 클린 아키텍처를 적용한 상태한 안드로이드 앱이다.
- 네트워크 라이브러리로,
okHttp3
와,Retrofit2
를 사용하고 있다. - 직렬화 라이브러리로
kotlinx.serialization
을 사용하고 있다. - 서버 개발자와 http response에 대한, request를 충분히 논의하고 합의할 수 있는 상태이다.
네트워크 예외 처리를 할 때, 참여하는 모든 안드로이드 개발자가 일관되고 가독성이 높게 개발하려면 어떻게 해야 할까?
기준
- 예외 처리 코드의 Indent 가 깊지 않고, 읽기 쉽게 한다.
- data layer 와 domain layer의 예외(Exception) 가 Presentation layer 에서 catch 가능하게 한다.
- 이유: 유저에게 Error Event를 보여줘야 함으로
- data layer의 예외는 data layer에서, throw 하게 한다.
- 예외 이벤트의 이유를 세분화하여, 명확히 그 이유를 사용자에게 보여준다.
- 중복 코드를 최대한 줄인다.
과정
서버 개발자와 협의 하여, success 한 상태가 아닌 상황에 대한 커스텀 예외와 Error 타입을 정의한다.
OkHttp Interceptor
를 활용해서, 발생 가능한, data layer의네트워크 예외(IOException)
를 throw 한다.viewModel에서,
CoroutineExceptionHandler
를 선언하고, 여기서 일관되게 Error에 대한 Event를 발생시킨다.- 유저에게 Event를 보여주는 것 외에, 다른 작업이 필요한 경우는 그에 맞게 다르게 처리해야 한다.
Error Event 에 대해서, 유저에게 보여주는 방법은 일관되게 한다.
- Fragment or Activity들 에서 Event 처리함수를 동일하게 사용하여, Error 이유를 유저에게 Toast or SnackBar로 보여준다.
예시 코드
ErrorResponse
(data layer)
|
|
SuccessResponse
(data layer)
|
|
Api or Service
interface, (data layer)
|
|
RepositoryImpl
(data layer)
|
|
Repository
(domain layer)
|
|
ViewModel
(presentation layer)
|
|
Fragment or Activity
(presentation layer)
|
|
참고 사항
BaseViewModel 를 추상 클래스로 선언하고, 추상 함수(onError) 을 상속 받은 viewModel 을 통해 중복된 코드를 줄일 수도 있다.
네트워크 예외가 아닌, domain layer의 Usecase의 비지니스 로직에서 예외하는 것 까지 모두 일관되게 처리할 수 없다.
- 이 경우는 viewModel의
exceptionHandler
나 viewModel의 domain 호출 코드에서 예외처리를 그에 맞게 처리 해야 한다.
- 이 경우는 viewModel의
Reference
- https://square.github.io/okhttp/features/interceptors/
- https://square.github.io/okhttp/5.x/okhttp/okhttp3/-interceptor/index.html
- https://kotlinlang.org/docs/exception-handling.html#supervision-scope
- https://dongsik93.github.io/til/2022/07/05/til-kotlin-coroutine-exception-handling/
- https://tourspace.tistory.com/154?category=797357