runCatching은 코틀린 1.3 버전부터 지원된 캡슐화 블록으로 블록의 실행 결과가 Result의 형태로 리턴된다.
또한 실행 결과에 따른 프로퍼티, 함수들을 사용하여 유연한 이벤트 스트림으로 처리하여 가독성 있는 코드를 구현하는데 큰 도움이 된다.
runCatching 예시
val name: Result<String> = runCatching {
//String을 리턴하는 작업
"JMJ94"
}.onSuccess { it: String ->
it
}.onFailure { tr: Throwable ->
println("$tr")
}
runCatching은 실행 결과에 따른 프로퍼티를 제공한다.
isSuccess
runCatching 블록의 실행이 별문제 없이 성공한다면 result는 true고 문제가 발생한 경우는 false다.
val result = runCatching {
//do someting
}.isSuccess
isFailure
runCatching 블록의 실행에 문제가 발생했다면 result는 true고 문제가 없는 경우는 false다.
val result = runCatching{
//do someting
}.isFailure
이러한 프로퍼티를 활용하여 테스트 코드를 작성하거나 쓰임새에 따라 코드를 작성할 때도 가독성을 더 향상할 수 있다.
이제 성공 혹은 실패에 따른 캡슐화된 결과값 Result에서 값을 가져오는 함수들을 알아보자.
getOrNull()
runCatching 블록에서 에러가 발생한 경우 null을 리턴한다.
name.getOrNull()
getOrElse()
runCatching 블록에서 에러가 발생한 경우 Throwable을 인자로 받아 블록 안의 값을 리턴할 수 있다.
name.getOrElse{ tr: Throwable ->
}
getOrThrow()
runCatching 블록에서 문제가 발생한경우 그대로 에러를 리턴한다.
name.getOrThrow()
getOrDefault()
runCatching 블록에서 문제가 발생한 경우 defaultValue를 적용하여 리턴한다.
name.getOrDegfault(defaultValue = "기본값")
이번엔 Result의 확장함수 몇 가지를 알아보자.
먼저 소개할 map, mapCatching은 runCatching 블럭 수행이 성공한 후 호출되고, 수행 결과 값으로 특정 작업을 정의할 수 있다.
두 함수의 차이점은 두 함수의 블럭에서 발생한 에러 처리를 내부 또는 외부에서 처리할지에 대한 차이가 있다.
map()
map은 블록 내부에서 에러가 발생할 경우 에러를 바깥으로 전달한다.
try {
runCatching {
API.getUserName(id)
}.map { user ->
//에러 발생
throw Error("에러 발생")
}.onSuccess {
//map 블록에서 에러를 바같으로 보냈기 때문에 흐름이 끊겨 실행되지 않는다.
}.onFailure {
//map 블록에서 에러를 바같으로 보냈기 때문에 흐름이 끊겨 실행되지 않는다.
}
} catch (e: Exception){
//map으로부터 전달된 에러가 해당 인자로 들어옴
}
mapCatching()
mapCatching은 블록 에러를 내부적으로 onFailure를 통해 처리할 수 있다.
runCatching {
API.getUserName(id)
}.mapCatching { user ->
//에러 발생
throw Error("에러 발생")
}.onSuccess {
//mapCatching 블록에서 에러가 발생했기때문에 실행되지 않음
}.onFailure { tr:Throwable ->
//mapCatching 블록에서 전달된 에러와 함께 호출됨
}
recover, recoverCatching은 runCatching 블럭에서 에러가 발생하였을 경우 호출되고,
호출된 블럭의 수행 리턴 값을 onSuccess로 전달한다.
map과 마찬가지로 두 함수도 블럭에서 발생한 에러를 내부 또는 외부에서 처리할지에 대한 차이가 있다.
recover()
try {
runCatching {
throw Error("run 블럭 에러 발생")
}.recover { it ->
throw Error("revocer 에러 발생 ")
}.onFailure {
//호출되지 않음
}
} catch (e: Exception) {
//recover에서 던진 에러 처리
}
recoverCatching()
runCatching {
throw Error("run 블럭 에러 발생")
}.recoverCatching { it ->
throw Error("revocer 에러 발생")
}.onFailure { tr ->
//recover에서 던진 에러 처리
}
run 블록 성공 후 호출 | run 블록 실패시 호출 | 블록 내부 발생 에러 처리 | |
map | ✅ | ❌ | 외부에서 처리 |
mapCatching | ✅ | ❌ | 내부에서 처리 |
recover | ❌ | ✅ | 외부에서 처리 |
recoverCatching | ❌ | ✅ | 내부에서 처리 |
'Kotlin' 카테고리의 다른 글
[Kotlin] 스레드와 코루틴 (0) | 2022.05.12 |
---|---|
[Kotlin] CoroutineBuilder (0) | 2022.05.12 |
[Kotlin] Object (0) | 2022.03.25 |
[Kotlin] Delegated Properties (0) | 2022.03.23 |
[Kotlin] Delegation (0) | 2022.03.22 |