पाठ 19 / 25

Error Handling: Exceptions and Result

try as an expression, require, check and runCatching.

No checked exceptions

Kotlin has no checked exceptions: you are not forced to catch or declare them. try is an expression, so val n = try { s.toInt() } catch (e: NumberFormatException) { 0 } works. Standard preconditions are require(cond) (throws IllegalArgumentException for bad arguments), check(cond) (throws IllegalStateException for bad state) and error("msg"). Many functions have safe variants such as toIntOrNull(). Result<T> with runCatching { } wraps success or failure as a value, with getOrNull, getOrElse, map, onSuccess and onFailure. Note that runCatching also catches CancellationException, so be careful using it inside coroutines. For domain errors, a sealed result type is often clearer.

Errors, generics and Java interop

Real projects need clear error handling, reusable generic code and smooth interop with Java libraries.

Three ideas: exceptions and Result, generics with variance, Java interoperability.
Figure 7.1 — Kotlin code calling Java and Java calling Kotlin.

Preconditions, Result and a sealed outcome

Three styles side by side.

fun parsePort(raw: String): Int {
    val port = raw.toIntOrNull()
    require(port != null && port in 1..65_535) { "invalid port: $raw" }
    return port
}

fun readPort(raw: String): Int =
    runCatching { parsePort(raw) }
        .onFailure { println("falling back: ${it.message}") }
        .getOrElse { 8080 }

sealed interface Transfer {
    data class Done(val id: String) : Transfer
    data class Rejected(val reason: String) : Transfer
}

fun transfer(amount: Long, balance: Long): Transfer =
    if (amount <= balance) Transfer.Done("tx-1") else Transfer.Rejected("insufficient funds")

Exceptions for bugs, types for outcomes

Use exceptions for programming errors and unexpected failures; model expected business outcomes, such as "insufficient funds", as values in a sealed type so callers must handle them.

त्वरित जाँच: What does `check(condition)` throw when the condition is false?

  • Nothing; it only logs
  • `IllegalArgumentException`
  • `NullPointerException`
  • `IllegalStateException`
Answer

`IllegalStateException` — require is for arguments, check is for state.