[Kotlin] runCatching과 Result 타입

Harry The Great
해리의 유목코딩
4 min readDec 13, 2019

runCatching은 코틀린 1.3버전부터 도입된 캡슐화 블록입니다. runCatching 블록 안에서 성공/실패 여부가 캡슐화된 Result<T> 형태로 리턴합니다. 스위프트의 Result, 자바스크립트의 Promise와 유사하며 runCatching을 이용하면 코루틴 블록등을 RxJava에서 사용했던 것과 같이 유연한 이벤트스트림으로 처리할 수 있습니다.

runCatching 예시

프로퍼티

Result<T>타입은 isSuccess와 isFailure를 프로퍼티로 갖습니다.


if
(colorName.isSuccess){ //성공시 호출 }
if(colorName.isFailure){ // 실패시 호출}

또한 테스트코드 작성시 가독성이 더 좋게 작성할 수 있습니다.

Result 타입에서 값 가져오기

  • getOrThrow()
colorName.getOrThrow() 
// runBlocking문에서 에러가 발생한경우 해당에러를 리턴합니다.
  • getOrDefault
colorName.getOrDefault(defaultValue = "미상") 
//runBlocking문에서 에러가 발생한경우 defaultValue 파라미터를 리턴합니다.
  • getOrNull
colorName.getOrNull()
// runBlock문에서 에러가 발생한경우 null값을 리턴합니다.
  • getOrElse
colorName.getOrElse{ exception: Throwable -> }
// runBlocking문에서 에러가 발생한경우 exception을 인자로받아
// 블록안의 값을 리턴합니다.캡슐화된 타입값과 같아야하기때문에 다른타입을
// 리턴하고싶다면 아래 mapCatching을 사용해야합니다.

map, mapCatching

위 코드에서는 firstUserAge와 secondUserAge모두 getOrNull() 인스턴스 호출 시 123 값을 리턴합니다. 어떻게 보면 동일해 보이지만 블록 안의 에러가 발생한다면 다르게 처리됩니다.

map

map은 블록 안의 에러가 발생할경우 바깥으로 에러를 보냅니다.

mapCatching

mapCatching은 블록 안의 에러를 내부에서 처리하며 onFailure로 받을 수 있습니다.

recover, recoverCatching

map이 runCatching이 성공할 경우 호출되었다면 recover은 실패했을 경우 호출됩니다. 만약 runCaching문에서 에러가 발생할 경우 recover, recoverCatching문이 호출된 후 리턴 값을 onSuccess로 전달합니다. 하지만 map과 마찬가지로 블록 내에서 에러가 발생했을 경우 다르게 처리합니다.

recover

recoverCatching

주의사항

현재 kotlin.Result를 함수의 리턴타입으로 사용할 수 없으며 이를 해결하기위해서는 -Xallow-result-return-type를 추가해주어야 합니다. gradle에서 아래 라인을 추가함으로 해결할 수 있습니다.

android {
kotlinOptions {
freeCompilerArgs = ["-Xallow-result-return-type"]
}
}

현재 이러한 제약이 있는 이유에대해서는 아래 링크를 참조하실 수 있습니다.

마치며

기존 코 루틴이 rxjava에 비해 이벤트 흐름 처리에 대한 부분이 상세하게 다루기 어려웠는데 runCatching을 사용하면 이제 코 루틴만으로도 별도의 플러그인 없이 아주 쉽게 이벤트 처리를 할 수 있을 것 같습니다.

--

--

Harry The Great
해리의 유목코딩

Android & IOS Developer 😀 미디움 이외에 스니펫이나 디버그노트로 활용하는 https://www.harrymikoshi.com/ 블로그도 운영하고있습니다.