Android 개발/Retrofit, RxJava, RxAndroid, OKHttp

EOFException 발생시키는 empty body 대응 방법 # Retrofit

Developer88 2023. 5. 25. 02:53
반응형

Retrofit 을 이용해서 정상적으로 서버의 데이터를 요청하였을 때,

200 OK를 받았는데도,

서버에서 empty body를 주어서,

EOFException 이 발생하는 경우가 있습니다.

오늘은 이것의 대응 방법에 대해서 정리해 보겠습니다.

 

1. 서버 200 과 EOFException 

위에서 언급한 것처럼,

서버에서 200 OK 를 주었는데도,

body가 비워져 있어서,

EOFException 이 발생할 수 있습니다.

 

서버에서는 데이터 없으니 "" 를 보내버린 것이구요.

아래와 같이 body는 0-byte가 되어 있습니다.

 

 

 

보통은 서버에 데이터를 받을 때,

Retrofit 과 JSON 컨버터인 moshi(혹은 Gson)를 붙여서 사용하게 되는데요.

JSON으로 파싱하려고 하는데, body에 아무것도 없으니,

IOException 을 상속받은 EOFException 을 throw 합니다.

 

 

이것을 정상적인 경우라고 하기는 어려운데요.

서버와 클라이언트가 잘 협의하여 설계되었다면,

이런일이 발생하지 안았을테니 말이지요.

 

2. 대응방법

이런 상황이 발생하면, 어떻게 대응해 주어야 할까요?

서버와 잘 협의해서 empty body 말고, Parsing하는 데이터 구조에 맞추어서 보내주도록 할 수도 있을 것이구요.

 

moshi 같은 Converter를 위해서, body length가 0 일경우에 대응하는,

Custom Converter 를 작성해서 처리하는 방법도 있을 수 있습니다.

 

이 글에서는,

OKHttp 에 Interceptor 를 붙여서,

Custom한 Exception을 throw 한 다음,

해당 Exception을 catch 해서 대응하는 방법에 대해서 정리해 보겠습니다.

 

2-1. Custom Exception 

아래와 같이 EmptyBody에 대한 Custom 한 Exception을 먼저 생성해 줍니다.

 

class EmptyBodyException: IOException("Response body is empty")

 

2-2. Interceptor

이제 OkHttp 에 붙일 Interceptor를 아래와 같이 작성해 줍니다.

 

class EmptyBodyInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val response = chain.proceed(chain.request())
        if (response.body?.contentLength() == 0L && response.isSuccessful) {
            throw EmptyBodyException()
        }
        return response
    }
}

 

 

OkHttpClient 를 빌드할 때 아래와 같이 interceptor를 추가해주면 됩니다.

 

val client = OkHttpClient.Builder()
    .addInterceptor(EmptyBodyInterceptor())
    .build()

 

2-3. try...catch

이제 networkRequest 를 할 때 아래와 같이,

emptyList 를 반환해 주도록 catch 블록에서 처리해 주면 됩니다.

 

try {
    testApi.fetchTestNetwork(id)
} catch (e: EmptyBodyException) {
    emptyList<TestObject>()
}

 

728x90