Does Kotlin have multi-catch?

#4

The above is still true.

#5

I stumbled across this thread wondering the same thing…later I realized that a similar control flow can be achieved by nesting a when statement inside a catch block… Nothing revolutionary. I’d just like to share the idea.

try {
    // code
} catch(ex:Exception) {
    when(ex) {
        is SomeException,
        is AnotherException -> {
            // handle
        }
        else -> throw ex
    }
}

Eric

7 Likes
#6

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)

1 Like
#7

Has there been any progress on this?

Having to use @surplus.et 's suggestion is very cumbersome and bloated.

#8

Andrey’s message is still true. Multi-catch is not on the roadmap for 1.2, but it’s very likely that it will be added at a later time.

3 Likes
#9

when it is ready, please add inspections as well to collapse into multicatch

#10

Sure, we’ll do that.

1 Like
#11

Beginner here. Why this code

try {
    ...
} catch (e: Exception) {
    ...
} catch (e: JsonMappingException) {
    ...
} catch (e: UnrecognizedPropertyException) {
    ...
}

compiles fine? (I don’t think it works, but it does compile)

#12

It looks perfectly fine for me. There is no multicatch here.

1 Like
#13

Try listing the catch of the most specialised exception first, otherwise I suspect that catch (e: Exception) will catch all.

#14

I think use only catch (e: Exception) enough.

#15

Well, who knew that reading the documentation would be of any value :wink:

when matches its argument against all branches sequentially until some branch condition is satisfied

Of course in my case it didn’t work, since Exception was listed first.

#16

While we wait for the multicatch support I’ve created this extension that may help someone:

fun <R> Throwable.multicatch(vararg classes: KClass<*>, block: () -> R): R {
     if (classes.any { this::class.isSubclassOf(it) }) {
         return block()
     } else throw this
}

Usage:

try {
    ...
} catch (e: Exception) {
    e.multicatch(SomeException::class, OtherException::class) {
        // Shared catch execution
    }
}
5 Likes
#17

Thanks carlesic! That is a pretty reasonable work around! Wish I thought of it!

#18

It’s a pity it requires kotlin.reflect

1 Like
#19

You can avoid reflect and adding new method by using whenclause, it is not much longer:

try {
    ...
} catch (e: Exception) {
    when(e){
         is SomeException, is OtherException -> {...}
         else -> {}
    }
}
4 Likes
#20

To mimic multi-catch the else branch should rethrow the exception.

try {
    ...
} catch (e: Exception) {
    when(e) {
         is SomeException, is OtherException -> {...}
         else -> throw e
    }
}
2 Likes
#21

Is there an issue that we can vote for to get this in?

7 Likes
#22

Yes - https://youtrack.jetbrains.com/issue/KT-7128

It seems very odd that after 4 years this issue is still awaiting prioritisation.

I get that exceptions are not ‘cool’ from a functional perspective, but Kotlin is a General Purpose language, and allow succinct code in the main programming styles.

5 Likes
#23

Maybe they are actively considering union types, in which case multi-catch would follow for free.