Exceptions

Exceptions and try as an Expression

try is an expression: the value of the try block, or of whichever typed catch ran, is the result, and finally runs without changing it. require() throws IllegalArgumentException; check() and error() throw IllegalStateException.

Validating a cart quantity with try as an expressionKotlin
fun parseQuantity(input: String): Int {
  val n = input.trim().toInt()                    // may throw NumberFormatException
  require(n in 1..10) { "Quantity must be 1-10, was $n" }
  return n
}
fun main() {
  for (input in listOf(" 7 ", "two", "40")) {
    val qty = try {
      parseQuantity(input)
    } catch (e: NumberFormatException) { 1 }      // the subclass must come first
    catch (e: IllegalArgumentException) { println(e.message); 10 }
    println("'$input' -> $qty")
  }
}
Output
' 7 ' -> 7
'two' -> 1
Quantity must be 1-10, was 40
'40' -> 10

NumberFormatException extends IllegalArgumentException, and swapped clauses compile without a warning, sending "two" to the general handler. Kotlin has no checked exceptions, so nothing forces you to declare or catch anything (@Throws documents them for Java callers). throw has the type Nothing, so catalog.find { ... } ?: error("not found") is still a Book. For expected failures, prefer toIntOrNull() with ?:, or runCatching { }, which returns a Result. Cancellation covers coroutines.