- kotlin Error Handle을 하기 전에 어떠한 상황에서 에러 상황을 처리할지 정해야 한다.
- Type-safe Error Handling → Either Type
- Either Type은 Left && Right에 특정 value가 들어갔을때 미리 정의한 type과 일치하지 않는다면 .left() && .right() 를 사용해 success/fail을 커스텀할 수 있다.
sealed class Either<out L, out R> data class Left<L>(val value: L): Either<L, Nothing>() / error data class Right<R>(val value: R): Either<Nothing, R>() // success
- Sealed class는 하나의 type value를 사용하는 제한적인 상황일때 다양한 기능을 해당 value로 구현해야 한다면 유용한 클래스이다.
- 또한 sealed class는 상속(abstract) 클래스이다.
- 그렇다면 sealed class와 enum 클래스의 차이점은 무엇인가?
- 둘은 많은 부분에서 흡사하지만 단 한가지 다른점은 enum은 오직 single sample을 가지고 여러개의 subclass를 가질 수 없다는 점이다.
그렇다면 sealed class 를 어떤 경우에 사용하는가?
- 다양한 경우에 활용할 수 있지만 user에게 요청이 들어왔을때 status를 보내주는 상황에서 사용할 수 있다. success/fail 을 구분해 정의하여 원하는 structure를 전달해 줄 수 있다.
- 또한 sealed class를 결과값으로 만들기 위해서는 어떻게 사용해야 할까? repositry영역에 class를 정의해서 사용할 수도 있다.
interface FeedRepositry {
fun getFeeds(): LiveData<List<Feed>>
}
Result vs runCatching
- result와 runcatching은 활용되어지는 영역이 다르다. 먼저 result는 단순히 성공/실패를 구분할 수 밖에 없다
- 다음은 result에 대한 예제이다
class JobService(private val jobs: Jobs) {
fun printOptionJob(jobId: JobId) {
val maybeJob: Result<Job?> = jobs.findById(jobId)
if (maybeJob.isSuccess) {
maybeJob.getOrNull()?.apply { println("Job found: $this") } ?: println("Job not found for id $jobId")
} else {
println("Something went wrong: ${maybeJob.exceptionOrNull()}")
}
}
}
- getOrNull은 Result 또는 null을 returns 한다.
- getOrThrow는 Result 또는 Result.Failure에 선언된 exception을 throw 한다.
- getOrDefault는 Result 또는 Result에 default로 선언된 값을 failure값으로 returns 한다.
mapCatching
- mapCatching function은 value 값을 변환시키거나 Result에 선언된 exception을 throw 해준다.
class CurrencyConverter {
@Throws(IllegalArgumentException::class)
fun convertUsdToEur(amount: Double?): Double =
if (amount != null && amount >= 0.0) {
amount * 0.91
} else {
throw IllegalArgumentException("Amount must be positive")
}
}
- 위 코드의 converter는 null이나 부정 값일 경우 throw 한다.
Recover
try {
runCatching {
throw Error("runBlock문 에러발생")
}.recover { it: String ->
throw Error("recover문 에러발생")
}.onFailure {
//에러가 전달되지않습니다.
}
} catch (e: Exception) {
//recover에서 발생한 에러가 받아집니다.
}
RecoverCatching
runCatching {
throw Error("runBlock문 에러발생")
}.recoverCatching { it: String ->
throw Error("recover문 에러발생")
}.onFailure {
//이곳에서 에러를 받습니다.
}
- runCatching이 성공할 경우 호출되었다면 recovery은 실패했을 경우 호출된다. 만약 runCatching 문에서 에러가 발생할 경우 recovery, recoverCatching 문이 호출된 후 onSuccess로 전달된다. 하지만 map 과 마찬가지로 블록 내에서 에러가 발생했을 경우 다르게 처리한다.
- mapCatching 또한 블록 안의 에러를 내부에서 처리하며 onFailure로 받을 수 있다.
'Kotlin' 카테고리의 다른 글
JSON 직렬화가 왜 안돼?.. (1) | 2024.11.24 |
---|---|
[Kotlin] Result란? (0) | 2023.09.12 |
Run Catching (0) | 2023.03.01 |
[Kotlin] 기초 (0) | 2022.08.01 |