Kotlin Exception Handling

Kotlin uses try/catch/finally blocks and the throw keyword for exception handling. Checked exceptions do not exist; all exceptions are unchecked, simplifying call sites but requiring discipline.

1. Throwing Exceptions

Use throw to signal an error. Any Throwable can be thrown.

fun fail(message: String): Nothing {
  throw IllegalStateException(message)
}

2. try/catch as Expression

A try block can return a value. Catch specific exceptions in catch clauses.

val result: Int = try {
  parseInt("abc")
} catch (e: NumberFormatException) {
  println("Parsing error: \${e.message}")
  -1
}

3. Multiple catch Blocks

Chain catch clauses to handle different exception types.

try {
  // code that may throw
} catch (e: IllegalArgumentException) {
  println("Bad argument")
} catch (e: IllegalStateException) {
  println("Bad state")
}

4. finally Block

finally runs after try/catch whether or not an exception occurred, typically for cleanup.

val stream = openStream()
try {
  process(stream)
} catch (e: IOException) {
  println("IO error")
} finally {
  stream.close()
}

5. try-with-Resources Equivalent

Kotlin does not have built-in try-with-resources, but use extension functions on use for AutoCloseable.

FileInputStream("file.txt").use { stream ->
  // stream is closed automatically
  process(stream)
}

6. Null-Safe Call with Exception

Leverage the Elvis operator to throw if null.

val s: String? = getStringOrNull()
val nonNull: String = s ?: throw NullPointerException("Value was null")

7. Custom Exceptions

Define your own exception types by subclassing Exception or RuntimeException.

class MyAppException(message: String): RuntimeException(message)

throw MyAppException("Something went wrong")

8. Exception Handling Best Practices

• Avoid catching broad Exception or Throwable.
• Catch only what you can handle.
• Use specific exception types.
• Clean up resources in finally or use.
• Document when functions may throw exceptions.
• Prefer return types like Result or nullable types for recoverable errors.

9. Using Result for Functional Error Handling

Kotlin’s Result type can encapsulate success or failure without exceptions at call site.

fun safeParse(s: String): Result<Int> =
  runCatching { s.toInt() }

val r = safeParse("123")
r.onSuccess { println("Parsed: \$it") }
 .onFailure { println("Error: \${it.message}") }

10. Summary

Kotlin’s exception model is simple: unchecked exceptions only, try/catch/finally expressions, and use for resource management. Combine with Result for functional style error handling. Always catch specific exceptions, clean up resources, and document function failure modes.

Previous: Kotlin TreeMap | Next: Kotlin Operator Overloading

<
>