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
}
}