Kotlin Tutorial · Advanced Kotlin · Lesson 24 of 31
Kotlin Exceptions and Result
Throw and catch exceptions, use try as an expression, preconditions with require and check, and runCatching.
try is an expression
Kotlin has no checked exceptions: you don't declare what a function throws. try/catch is an expression,
so it can produce a value. require(...) throws IllegalArgumentException for bad arguments and check(...)
throws IllegalStateException for bad state.
fun parseQuantity(text: String): Int {
val n = text.toInt() // throws NumberFormatException for bad input
require(n > 0) { "quantity must be positive, got $n" }
return n
}
fun main() {
for (input in listOf("3", "abc", "-1")) {
val qty = try {
parseQuantity(input)
} catch (e: NumberFormatException) {
println("not a number: $input")
0
} catch (e: IllegalArgumentException) {
println(e.message)
0
} finally {
println("checked '$input'")
}
println("qty=$qty")
}
}
Output
checked '3' qty=3 not a number: abc checked 'abc' qty=0 quantity must be positive, got -1 checked '-1' qty=0
Run this on your computer — see “Get Started” for setup.
Result and runCatching
runCatching { } turns an exception into a Result value you can transform with map, getOrElse and
onFailure. For expected failures (validation, not found), many codebases prefer a sealed result type instead.
fun fetchPrice(sku: String): Double =
if (sku.startsWith("A")) 9.99 else throw NoSuchElementException("unknown sku $sku")
fun main() {
val ok = runCatching { fetchPrice("A-1") }
val bad = runCatching { fetchPrice("Z-9") }
println(ok.map { it * 2 }.getOrNull())
println(bad.isFailure)
bad.onFailure { println("failed: ${it.message}") }
println(bad.getOrElse { 0.0 })
}
Output
19.98 true failed: unknown sku Z-9 0.0
Run this on your computer — see “Get Started” for setup.
Test yourself
What does require(condition) throw when the condition is false?
IllegalStateExceptionIllegalArgumentExceptionNullPointerExceptionNothing; it returns false
Show answer
Answer: IllegalArgumentException