룬아님의 취중코딩

RxJava + Retrofit2 Error 객체로 받아 커스텀 하기 본문

개발/안드로이드 개발

RxJava + Retrofit2 Error 객체로 받아 커스텀 하기

룬아님 2019. 11. 25. 19:12

API요청을 하였을 때

{"code":"permission_denied","detail":"이 작업을 수행할 권한(permission)이 없습니다.","message":"이 작업을 수행할 권한(permission)이 없습니다."}

이런 형태로 error response가 돌아왔다.
그래서 해당 reponse의 message를 바로 snackBar에 띄우고 싶어서 Gson으로 객체를 만들고 거기에서 message만 뽑아서 Throwable을 만들어 주도록 수정했다.

 

1. ErrorInterceptor.kt

private val UTF8 = Charset.forName("UTF-8")

class ErrorInterceptor : Interceptor {
    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val originalRequest = chain.request()
        val response = chain.proceed(originalRequest)

        return if (response.code() >= 400) {
            throwError(response)
            response
        } else {
            response
        }
    }

    @Throws(IOException::class)
    private fun throwError(response: Response) {
        val responseBody = response.body()
        if (responseBody != null) {
            val source = responseBody.source()
            source.request(java.lang.Long.MAX_VALUE) // Buffer the entire body.
            val buffer = source.buffer()

            var charset = UTF8
            val contentType = responseBody.contentType()
            if (contentType != null) {
                charset = contentType.charset(UTF8)
            }

            if (responseBody.contentLength() != 0L) {
                val responseJSON = buffer.clone().readString(charset)
                val message: String?
                try {
                    message = Gson().fromJson(responseJSON, ErrorResponse::class.java).message
                    throw Throwable(message)
                } catch (error: JsonParseException) {
                    throw Throwable("")
                }
            }
        } else {
            throw Throwable("")
        }
    }
}

 

2. OkHttpClient

OkHttpClient.Builder().apply {
            
            ...
            
            addInterceptor(ErrorInterceptor())
            
            ...
            
        }.build()

 

구현한 Interceptor를 등록해주면

.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
        { _isLoginSuccess.value = Event(true) },
        {
            if (it.message.isNullOrEmpty()) {
                _snackbarText.value = Event(R.string.error_message_unknown)
            } else {
                _snackbarText.value = Event(it.message!!)
            }
        })

onError에서 위에서 직접 커스텀한 결과값을 바로 받아볼 수 있다.

반응형
Comments