반응형
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
data class Check(val message: String) : Result<Nothing>()
data class Error(val message: String) : Result<Nothing>()
override fun toString(): String {
return when (this) {
is Success<*> -> "Success[data=$data]"
is Check -> "Type Check[message=$message]"
is Error -> "Error[exception=$message]"
}
}
}
sealed class를 사용할 경우 enum과는 달리 여러가지 형태의 데이터 유형을 선택할 수 있다.
위와 같이 Sucess class, Check class, Eror class와 같이 다양항 유형이 가능하다.
suspend fun <T> getResult(call: suspend () -> Response<T>): Result<T> {
return runCatching {
val response = call()
if (response.isSuccessful) {
Result.Success(response.body()!!)
} else if (response.code() == NOT_FOUND){
Result.Error(response.message() ?: "NotFound")
} else if (response.code() == VALIDATION_ERROR){
Result.Check(response.message() ?: "Type Error")
} else {
Result.Error(response.message() ?: "Error")
}
}.getOrDefault(Result.Error("Network error"))
}
결과를 처리할 때도 Result타입으로 반환하지만 Success, Error, NoResponse와 같이 다양한 형태를 wrapping하여 리턴이 가능하다. (when으로 구현 해줄 경우 모든 경우를 다 처리 해주거나 else를 이용하여 처리해 주어야 한다.)
val Result<*>.succeeded
get() = this is Result.Success && data != null
val <T> Result<T>.message: String?
get() = (this as? Result.Error)?.message
위와 같은 extension을 통해 아래와 같이 data를 직접 가져오는 거나 에러 메시지를 출력하는 것이 가능하다.
override suspend fun execute(): Boolean {
return infoRepository.getHealth().succeeded
}
override suspend fun getInfo(): RemoteResult<List<Pet>> {
val result = getResult { userInfoService.getPets() }
Log.e("getInfo", result.message.toString())
return result
}
반응형
'안드로이드' 카테고리의 다른 글
컴포즈 부수효과 (0) | 2022.07.30 |
---|---|
Compose의 Stateful과 Stateless 개념 (0) | 2022.06.27 |
안드로이드 테스팅 (0) | 2022.05.28 |
광고 정책 위반으로 앱 삭제 대응 (0) | 2021.06.23 |
안드로이드 postValue (0) | 2021.05.29 |