Introduction: Why This Topic Blows Up on Stack Overflow?
\n\nIf you've ever written in Kotlin and needed to catch multiple different exceptions, you know it can be painful. Especially if you come from Java, where multi-catch (catch (IOException | SQLException e)) is standard since Java 7. In Kotlin, it's different, and many developers get lost.
The question "How to catch many exceptions at the same time in Kotlin?" on Stack Overflow has gathered thousands of views. And this is no coincidence: error handling is something everyone encounters. Today we'll solve this problem once and for all.
\n\nIn this article you will learn:
\n- \n
- Why multi-catch in Kotlin doesn't work like in Java \n
- How to catch multiple exceptions elegantly and compactly \n
- When to use
whenincatch, and when to use good oldif\n - Real examples from production code \n
Let's go!
\n\nThe Problem: Where Is My Multi-Catch?
\n\nIn Java you simply write:
\ntry {\n riskyOperation()\n} catch (IOException | SQLException e) {\n // handle identically\n}\n\n\nNice, concise, clear. But in Kotlin, this syntax does not exist. If you try to write catch (IOException | SQLException e), the compiler will say "no".
Why? Because Kotlin chose explicitness and cleanliness. The language designers decided that multi-catch with a vertical bar isn't quite Kotlin style. But that doesn't mean you can't catch multiple exceptions. It's just done differently.
\n\nLet's look at three main approaches.
\n\nMethod 1: Multiple catch Blocks (The Most Obvious)
\n\nThe simplest way is to just add several catch blocks in a row. Kotlin supports this perfectly.
try {\n val data = loadData()\n processData(data)\n} catch (e: IOException) {\n println("I/O error: ${e.message}")\n} catch (e: SQLException) {\n println("Database error: ${e.message}")\n} catch (e: Exception) {\n println("Unknown error: ${e.message}")\n}\n\n\nPros:
\n- \n
- Extremely clear — each exception type is handled separately \n
- You can provide different logic for different errors \n
- Great readability for beginners \n
Cons:
\n- \n
- Lots of code duplication if the handling logic is the same \n
- With 5+ exceptions, the block becomes bulky \n
Method 2: catch with when (Elegant and Flexible)
\n\nThis is where Kotlin truly shines. Instead of multi-catch, you can use when inside a single catch block.
try {\n val result = fetchFromNetwork()\n saveToDatabase(result)\n} catch (e: Exception) {\n when (e) {\n is IOException -> handleNetworkError(e)\n is SQLException -> handleDatabaseError(e)\n is SecurityException -> logAndNotify(e)\n else -> throw e // rethrow if we don't know how to handle\n }\n}\n\n\nThis approach is a real gem. It allows you to:
\n- \n
- Handle different exceptions in one place \n
- Use all the power of
when, including condition checks \n - Easily add new exception types \n
Here's a more advanced example with conditions:
\n\ntry {\n connectToService()\n} catch (e: Exception) {\n when {\n e is IOException && e.message?.contains("timeout") == true -> \n println("Connection timeout, retrying")\n e is IOException -> \n println("Network error: ${e.message}")\n e is SQLException && e.errorCode == 1045 -> \n println("Database authentication error")\n else ->