Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch many exceptions at the same time in Kotlin?

try { 

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

or

try { 

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

As a result, a compilation error: Unresolved reference: MyException2.

How can I catch many exceptions at the same time on Kotlin?

like image 499
Ant20 Avatar asked Apr 21 '16 05:04

Ant20


People also ask

How can I get multiple exceptions at once?

When catching multiple exceptions in a single catch block, the rule is generalized to specialized. This means that if there is a hierarchy of exceptions in the catch block, we can catch the base exception only instead of catching multiple specialized exceptions.

Can I use more than one try block to catch multiple exceptions?

A try block can be followed by one or more catch blocks. Each catch block must contain a different exception handler. So, if you have to perform different tasks at the occurrence of different exceptions, use java multi-catch block.

How multiple exceptions are handled?

By handling multiple exceptions, a program can respond to different exceptions without terminating it. In Python, try-except blocks can be used to catch and respond to one or multiple exceptions. In cases where a process raises more than one possible exception, they can all be handled using a single except clause.


2 Answers

Update: Vote for the following issue KT-7128 if you want this feature to land in Kotlin. Thanks @Cristan

According to this thread this feature is not supported at this moment.

abreslav - JetBrains Team

Not at the moment, but it is on the table

You can mimic the multi-catch though:

try {
    // do some work
} catch (ex: Exception) {
    when(ex) {
        is IllegalAccessException, is IndexOutOfBoundsException -> {
            // handle those above
        }
        else -> throw ex
    }
}
like image 56
miensol Avatar answered Oct 03 '22 10:10

miensol


To add to miensol's answer: although multi-catch in Kotlin isn't yet supported, there are more alternatives that should be mentioned.

Aside from the try-catch-when, you could also implement a method to mimic a multi-catch. Here's one option:

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

And using it would look like:

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

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

You'll want to use a function to produce a lambda rather than using a raw lambda as shown above (otherwise you'll run into "MANY_LAMBDA_EXPRESSION_ARGUMENTS" and other issues pretty quickly). Something like fun attempt(block: () -> Unit) = block would work.

Of course, you may want to chain objects instead of lambdas for composing your logic more elegantly or to behave differently than a plain old try-catch.

I would only recommend using this approach over miensol's if you are adding some specialization. For simple multi-catch uses, a when expression is the simplest solution.

like image 39
Aro Avatar answered Oct 03 '22 10:10

Aro