如何在Kotlin中同时捕获许多异常


82
try { 

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

要么

try { 

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

结果,出现编译错误:Unresolved reference: MyException2

如何在Kotlin上同时捕获许多例外?

Answers:


95

更新:如果您希望此功能登陆Kotlin,请投票给以下问题KT-7128谢谢@克里斯汀

根据此线程,目前不支持此功能。

阿布雷斯拉夫-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 '17

1
@IARIelse子句会抛出不需要的异常。
miensol


2
即使您抛弃了优雅和丑陋的论点,在这种情况下,Kotlin(声称很简洁)实际上是Java的2

2
这是由Detekt标记的,因为您捕获的异常太笼统;-)
kenyee 18'Aug

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
    }
}

您将要使用一个函数来生成一个lambda,而不是使用如上所示的原始lambda(否则,您很快就会遇到“ MANY_LAMBDA_EXPRESSION_ARGUMENTS”和其他问题)。这样的东西fun attempt(block: () -> Unit) = block会起作用。

当然,您可能希望链接对象而不是lambda,以便更优雅地构成逻辑或表现得比普通的try-catch不同。

如果要添加一些专业化,我只建议在miensol上使用这种方法。对于简单的多捕获用途,when表达式是最简单的解决方案。


如果我对它的理解正确,那么您可以在捕获中传递类,但是paramexceptions会接收对象。
nllsdfx

您真棒@aro,感谢您提供此替代方法
mochadwi

这种选择是好的,谢谢Aro :)总比没有好。但是,我希望他们能够使用该功能,尽管我的问题KT-7128是5年前打开的:-)
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上的我的库中查看

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.