Android/Today I Learned

네트워크 요청 실패했는데, RunCatching onSuccess 가 호출?

Nanamare 2022. 6. 23. 00:07
728x90

TL;DR
"네트워크 응답을 Result 와 같은 클래스로 래핑하면 실수할 확률이 높습니다."
상태 코드가 필요하면 awaitResponse 를 이용하고 아니라면 await 를 사용 합시다

해당 게시물은 실무에 도움이 되는 지식은 없고, 단순히 호기심으로 진행되었습니다.

회사에서 레거시 코드를 건드리는 중에, 신기한 일을 경험하였습니다.

runCatching { apiCall.await() }
    .onSuccess {
   	    // ...
    }
    .onFailure {
        // ...
    }

와 같은 코드에서 네트워크 요청이 실패하여 400 이상 상태 코드들이 내려오는데 모두 onSuccess 를 타고 있었습니다.

문제가 있던 apiCall.await() 의 자료형은 아래와 같았습니다.
apiCall 이 RxJava Single 로 되어 있어, coroutine 에서 제공하는 메서드 await 사용하고 있었습니다.

문제가 있는 클래스


일반적인 처리에서 접근하면 HttpException 이 반환되고 결과적으로 RunCatching 의 onFailure 에서 Throwable 로 전달되게 됩니다. 하지만 응답을 parsing 하는 과정에서 Result 로 래핑이 되기 때문에 HttpException 을 가진 Result 객체가 반환 됩니다.

여기서 부터 문제가 시작 됩니다.
RxJava 의 입장에서는 HttpException 을 가진 Result 객체는 결과적으로 에러가 아니기 때문에 onError 호출되지 않고 onSuccess 가 호출됩니다.

SingleSubscribeOn 클래스


그리고 await 의 onSuccess 이후 continuation 의 resume 메서드가 호출됩니다.


결론에 거의 다왔습니다. resume 메서드안에서는 Result.success 로 래핑해서 반환 하고 있습니다.


그렇기 때문에, runCatching 의 onSuccess 가 호출될 수 있었습니다.


실무에 도움이 될만한 부분은 없었지만, 왜 onSuccess 가 호출되는지 알게되어 호기심이 해결되었습니다.

글을 마치며 여러분께 질문 드려봅니다. 그럼 Retrofit 에서 제공하는 Response 클래스나 다른 클래스들로 래핑하게 되면 어떤일이 일어날까요?

그럼 저는 20000

728x90