Clean Architecture ErrorHandling in Android — 1

Jinwoo
DMSforDSM
Published in
5 min readDec 6, 2019

CleanArchitecture에서 ErrorHandling은 어디서 해야할까요?

처음 CleanArchitecture를 접했을 때 Presentation Layer에서 ErrorHandling을 해야 한다고 생각할 수도 있습니다. 하지만 Presentation Layer는 error를 처리하기 위한 HttpException 등의 Exception을 알지 못합니다.

그러면 Domain Layer는 어떠할까요? Domain Layer는 비즈니스 로직을 담당하는 곳입니다. 그 외의 것은 알지 못합니다.그렇기 때문에 Domain Layer 역시 HttpResponseCode나 Exception을 정확히 알지 못해 ErrorHandling과는 적합하지 않습니다.

그러니 ErrorHandling은 Api, DB를 알고 있는 Data Layer에 위치해야 합니다.

CleanArchitecture ErrorHandling 적용해볼까요?

주의!

저는 프로젝트에서 네트워크 연결이 불안정해도 데이터를 공급받을 수 있는 오프라인 모드를 적용했습니다. 그래서 Api를 통해 받아온 데이터를 DB에 저장하고 저장한 데이터를 가저오는 방식을 사용했습니다.

하지만 저부터도 아직 오프라인모드에 대해서는 완전히 이해하고 구현했다고 확신이 들지 않기 때문에 그 점을 고려하고 로직을 봐주시길 바랍니다.

처음 시작해봅시다

처음엔 가져온 데이터가 Api를 통해 가져온 데이터인지 로컬 DB에서 가져온 데이터인지를 판별하여 Api가 성공적으로 불러져왔는지 확인할 필요가 있었습니다.

그래서 다음과 같이 isSuccess라는 변수를 각 Entity마다 추가하여서 성공적인 데이터 값인지 판별해주었습니다.

하지만 이와 같은 방법에는 문제가 있었습니다.

이런 방식을 차용하게 된다면 모든 Entity에는 isSuccess라는 변수가 추가되는 번거로움이 있을 뿐더러 ErrorHandling을 하기 위해서 Entity를 수정하는 일은 일어날 수 없는 일이었기 때문입니다.

변화해봅시다

그럼 Entity를 수정하지 못하면 Data Layer는 Exception를 어떻게 전달하고 presentation은 Exception이 어떻게 발생했는지 알 수 있을까요?

바로 ErrorHandlerEntity를 만드는 것입니다. ErrorHandlerEntity는 성공여부와 어떠한 에러인지를 알 수 있는 메시지를 담아 구성합니다.

그리고 Service에서는 다음과 같이 Kotlin의 Pair를 활용해 Pair<T, ErrorHandlerEntity> 형태로 데이터를 반환해줍니다.

그러면 Repository에서는 Data Layer와 Domain Layer사이를 연결해줘서 데이터를 전달해주는데 ErrorHandling은 Service에서 ErrorHandling을 해야할까라는 생각이 듭니다.

하지만 Service 또한 domain에 속하고 비즈니스로직을 처리하는 부분이라서 ErrorHandling을 해주어서는 안됩니다.

그래서 각 Service마다 ErrorHandler를 만들어 다음과 같이 Domain에 interface를 만들어줍니다.

하지만 구현체인 ErrorHandlerImpl는 Data Layer에 위치하게 합니다.

그러면 제어의 역전으로 인해 Domain Layer에서는 Handler를 호출하지만 자유롭게 ErrorHandling을 신경쓰지 않고 비즈니스 로직을 작성할 수 있습니다.

이렇게 사용자가 원하는 ErrorHandling된 데이터가 UseCase를 거칩니다.

최종적으로 데이터가 Presentation Layer로 넘어가면 Presentation Layer에서는 편리하게 처리해줍니다.

결론

아무리 고민을 해서 제 머릿속에서 나온 것이지만 이 것이 완전한 구조이고 정답이라고는 할 수 없습니다.

하지만 IoC와 Kotlin만의 타입인 Pair를 사용해 Domain Layer가 ErrorHandling을 신경쓰지 않고 비즈니스 로직을 처리할 수 있게 했고 Clean Architecture에 맞게 규칙을 지키며 ErrorHandling을 했습니다.
그점에 의의를 두려고 합니다.

그치만 무엇인가 잘못된 점이 있다면 댓글을 남겨주시거나 이메일(sugwer7464@gamail.com)로 보내주시면 감사하겠습니다.

프로젝트

다음과 같은 ErrorHandling 방식을 적용한 프로젝트와 저의 깃허브이니 참고해주세요!!

--

--