상세 컨텐츠

본문 제목

[Kotlin, Android] sealed class

카테고리 없음

by 개발혱 2021. 5. 16. 18:45

본문

enum 클래스의 확장형태.

 

android에서 활용 예제

- REST API 사용시에 네트워크 사용 시, success, error, data로 리턴 타입에 정해진 규약을 사용할 경우

- enum 형태로 써야하는 타입이 붙을 때 else에 대한 예외 처리 없이 타입으로 써야하는 경우.

sealed class ResultWrapper<out T> {
    data class Success<out T>(val value: T): ResultWrapper<T>()
    data class GenericError(val code: Int? = null, val errorInfo: ErrorMessage? = null): ResultWrapper<Nothing>()
}
val NETWORK_ERROR_UNKNWON = 110
val NETWORK_ERROR_TIMEOUT = 111
val NETWORK_ERROR_CONNECT = 112
val NETWORK_ERROR_IOEXCEPTION = 113

suspend fun <T> safeApiCall(dispatcher: CoroutineDispatcher, apiCall: suspend () -> T): ResultWrapper<T> {
    return withContext(dispatcher) {
        try {
            ResultWrapper.Success(apiCall.invoke())
        } catch (throwable: Throwable) {
            when (throwable) {
                is IOException -> {
                    val code = NETWORK_ERROR_TIMEOUT
                    ResultWrapper.GenericError(code, null)
                }
                is SocketTimeoutException -> {
                    val code = NETWORK_ERROR_TIMEOUT
                    ResultWrapper.GenericError(code, ErrorMessage(Application.context?.getString(R.string.fail_to_connect_server)))
                }
                is UnknownHostException ->{
                    val code = NETWORK_ERROR_TIMEOUT
                    ResultWrapper.GenericError(code, ErrorMessage(Application.context?.getString(R.string.fail_to_connect_internet)))
                }
                is HttpException -> {
                    val code = throwable.code()
                    ResultWrapper.GenericError(code, ErrorMessage(throwable.message()))
                }
                else -> {
                    ResultWrapper.GenericError(null, null)
                }
            }
        }
    }
}

private fun convertErrorBody(throwable: HttpException): ErrorResponse? {
    return try {
        throwable.response()?.errorBody()?.source()?.let {
            val moshiAdapter = Moshi.Builder().build().adapter(ErrorResponse::class.java)
            moshiAdapter.fromJson(it)
        }
    } catch (exception: Exception) {
        null
    }
}