1️⃣ 데이터 흐름
service : BaseResponse<T>
👆🏻
datasource : BaseResponse<T>
👆🏻
repository : Result<T>
- Service
- DataSource
- Repository
- 반드시 safeApiCall 사용
- safeApiCall로 발생 가능한 모든 API 에러를 확인하며, 이에 따라 Result 반환
- succes : response 내 data 전달
- failure : 앱 자체적으로 정의한 ApiError로 적절히 매핑해 전달
- BadRequest 세부 분기 처리 필요한 API라면, safeApiCall에 recoverCatching 붙여 serverCode에 따라 분기 처리
- 이때 분기는 해당 API에만 적용되는 BadRequest 규약을, sealed interface로 직접 정의해 사용
2️⃣ SafeApiCall
SafeApiCall은 다음 역할을 수행한다.
- suspendRunCatching 적용
- Throwable 없다면 → Success로 감싸 반환
- 발생 했다면 →
- CancellationException : throw
- 그 외 : Failure로 감싸 반환
- suspendRunCatching에서 Throwable 발생하지 않았다면
- handleReponse 적용
- 서버 개발자 실수 대응 (httpStatusCode는 성공이나, serverCode는 실패인 경우)
- serverCode가 성공을 의미한다면 Success로 감싸 데이터 반환
- data가 null이라면 ServerError throw (서버 규약에 의해 data는 null이 될 수 없음)
- serverCode가 에러를 의미한다면 서버 규약에 따라 올바른 ApiError로 분기해 throw
- suspendRunCatching에서 Throwable 발생했다면
- HttpException인 경우 → parseHttpException을 통해 serverCode를 읽고, 서버 규약에 따라 올바른 ApiError로 분기
- UnknownHostException, SocketTimeoutException인 경우 → NetworkError
- ApiError → handleResponse에서 넘어온 데이터로, 이미 ApiError 매핑 완료되었으므로 그대로 throw
- 그 외 → Unknown 처리
parseHttpException을 위해 json 객체가 필요하므로 hilt에 의해 싱글톤으로 관리되는 ApiResponseHandler 클래스 내부에 둔다.