본문 바로가기

프로그래밍 언어/Kotlin

runCatching 예외 처리

runCatching은 Kotlin에서 제공하는 예외처리 함수로 성공, 실패에 따른 결과를 Result 객체로 변환하여 반환한다.

inline fun <R> runCatching(block: () -> R): Result<R>
inline fun <T, R> T.runCatching(block: T.() -> R): Result<R>

 

Result 생성

runCatching 내부적으로도 try-catch문을 사용하여 작업의 성공, 실패 여부를 통해 Result 객체의 value 를 설정한다.

@InlineOnly
@SinceKotlin("1.3")
public inline fun <R> runCatching(block: () -> R): Result<R> {
    return try {
        Result.success(block())
    } catch (e: Throwable) {
        Result.failure(e)
    }
}

 

성공 시 value는 해당 타입의 데이터로, 실패 시 넘어온 Throwable을 Result 클래스 내부에 선언되어 있는 Failure 객체에 넘겨 value 값을 설정한다. 

@Suppress("INAPPLICABLE_JVM_NAME")
@InlineOnly
@JvmName("success")
public inline fun <T> success(value: T): Result<T> =
    Result(value)

/**
 * Returns an instance that encapsulates the given [Throwable] [exception] as failure.
 */
@Suppress("INAPPLICABLE_JVM_NAME")
@InlineOnly
@JvmName("failure")
public inline fun <T> failure(exception: Throwable): Result<T> =
    Result(createFailure(exception))
    
@PublishedApi
@SinceKotlin("1.3")
internal fun createFailure(exception: Throwable): Any =
    Result.Failure(exception)
    
internal class Failure(
    @JvmField
    val exception: Throwable
) : Serializable {
    override fun equals(other: Any?): Boolean = other is Failure && exception == other.exception
    override fun hashCode(): Int = exception.hashCode()
    override fun toString(): String = "Failure($exception)"
}

 

Result 객체 사용

전달 받은 Result 객체는 다음과 같이 사용할 수 있다.

fun test(){
    val result = runCatching{ doSomething(true) }
    result
        .onSuccess { value ->
            // 성공 작업 수행
            println(value)
        }.onFailure { e: Throwable ->
            // 실패 시 예외 처리
            println(e.message)
        }

    // 성공, 실패에 대한 반환
    val resultSuccess: Boolean = result.isSuccess
    val resultFailure: Boolean = result.isFailure
    
    val a: String? = result.getOrNull()
    val b: String = result.getOrThrow() // value 타입이 Failure인 경우 Throw
    val c: String = result.getOrElse {"Failure" }
    val d: String = result.getOrDefault("Failure")
}

private fun doSomething(error: Boolean): String{
    if(error) {
        throw Exception("Failure")
    }

    return "Success"
}

 

runCatching을 사용하면 다양한 편리한 기능들을 사용할 수 있지만 Result 객체를 생성하기 때문에 무작정 사용하는 것보단 상황에 맞게 사용해야 한다.

'프로그래밍 언어 > Kotlin' 카테고리의 다른 글

[Kotlin] 정렬  (0) 2024.06.11
[Kotlin] 배열과 리스트 복사  (0) 2024.03.06
[Kotlin] 문자열 String  (0) 2023.11.03
[Kotlin] 코틀린 기초 문법  (0) 2023.11.03