Kotlin에서 동시에 많은 예외를 포착하는 방법


84
try { 

} catch (ex: MyException1, MyException2 ) {
    logger.warn("", ex)
}

또는

try { 

} catch (ex: MyException1 | MyException2 ) {
    logger.warn("", ex)
}

결과적으로 컴파일 오류 : Unresolved reference: MyException2.

Kotlin에서 동시에 여러 예외를 포착하려면 어떻게해야하나요?

답변:


95

업데이트 : 이 기능을 Kotlin 에 적용하려면 다음 호 KT-7128에 투표 하세요. 감사합니다 @Cristan

스레드 에 따르면 이 기능은 현재 지원되지 않습니다.

abreslav-JetBrains 팀

지금은 아니지만 테이블 위에 있습니다.

그래도 멀티 캐치를 모방 할 수 있습니다.

try {
    // do some work
} catch (ex: Exception) {
    when(ex) {
        is IllegalAccessException, is IndexOutOfBoundsException -> {
            // handle those above
        }
        else -> throw ex
    }
}

2
나는 pdvrieze여기에 답장을 복사하고 있습니다 : This certainly works, but is slightly less efficient as the caught exception is explicit to the jvm (so a non-processed exception will not be caught and rethrown which would be the corollary of your solution)
solidak

1
@IARI이 else절은 원하지 않는 예외를 다시 발생시킵니다.
miensol


2
당신이 옆으로 우아함과 추함의 인수를 던져하더라도, 코 틀린는 (간결되는 주장)이 경우 Java와 같은 자세한으로 실제로는 2 배입니다
Phileo99

2
너무 일반적인 예외를 포착하고 있기 때문에 Detekt에 의해 플래그가 지정됩니다 ;-)
kenyee

8

miensol 의 답변에 추가하려면 Kotlin의 멀티 캐치가 아직 지원되지 않지만 언급해야 할 대안이 더 있습니다.

이외에도 try-catch-when멀티 캐치를 모방하는 방법을 구현할 수도 있습니다. 다음은 한 가지 옵션입니다.

fun (() -> Unit).catch(vararg exceptions: KClass<out Throwable>, catchBlock: (Throwable) -> Unit) {
    try { 
        this() 
    } catch (e: Throwable) {
        if (e::class in exceptions) catchBlock(e) else throw e
    }
}

그리고 그것을 사용하면 다음과 같습니다.

fun main(args: Array<String>) {
    // ...
    {
        println("Hello") // some code that could throw an exception

    }.catch(IOException::class, IllegalAccessException::class) {
        // Handle the exception
    }
}

위와 같이 원시 람다를 사용하는 대신 함수를 사용하여 람다를 생성 할 수 있습니다 (그렇지 않으면 "MANY_LAMBDA_EXPRESSION_ARGUMENTS"및 기타 문제가 매우 빠르게 발생합니다). 같은 fun attempt(block: () -> Unit) = block것이 작동합니다.

물론 논리를 더 우아하게 구성하거나 평범한 오래된 try-catch와 다르게 동작하기 위해 람다 대신 개체를 연결할 수 있습니다.

전문화를 추가하는 경우에만 miensol보다이 방법을 사용하는 것이 좋습니다 . 간단한 다중 캐치 사용의 경우 when표현식이 가장 간단한 솔루션입니다.


내가 올바르게 이해하면 캐치에서 클래스를 전달하지만 param exceptions은 객체를 취합니다.
nllsdfx

당신은 멋진 사람입니다 @aro,이 대안을 제공해 주셔서 감사합니다
mochadwi

이 대안은 좋습니다, 감사합니다 Aro :) 아무것도없는 것보다 낫습니다. 하지만 5 년 전에 제 호 KT-7128이 공개 되었음에도 불구하고 그들이 그 기능을 사용하기를 바랍니다. :-)
zdenda.online

-1

aro 의 예 는 매우 좋지만 상속이 있으면 Java 에서처럼 작동하지 않습니다.

귀하의 답변은 저에게 확장 기능을 작성하도록 영감을주었습니다. 상속 된 클래스도 허용하려면 instance직접 비교 하는 대신 확인해야합니다 .

inline fun multiCatch(runThis: () -> Unit, catchBlock: (Throwable) -> Unit, vararg exceptions: KClass<out Throwable>) {
try {
    runThis()
} catch (exception: Exception) {
    val contains = exceptions.find {
        it.isInstance(exception)
    }
    if (contains != null) catchBlock(exception)
    else throw exception
}}

사용 방법을 보려면 여기 GitHub의 내 라이브러리를 살펴 보세요.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.