Exceptions Workbook
Practice problems for Unchecked and Unbothered. Each takes a minute or two. Write your own answer first, then click Show answer — nothing here is a trick question, just direct practice of the syntax from the lesson.
try and preconditions
1. try as an expression
Assign number the result of parsing text as an Int, or 0 if it isn’t a valid number — using try/catch as an expression.
Show answer Hide answer
val number = try {
text.toInt()
} catch (e: NumberFormatException) {
0
} 2. Require an argument
Write sqrt(x: Double) that requires x >= 0, throwing IllegalArgumentException with a message otherwise.
Show answer Hide answer
fun sqrt(x: Double): Double {
require(x >= 0) { "x must be non-negative" }
return Math.sqrt(x)
} 3. Check state
Inside a method, throw IllegalStateException when isClosed is true, using the precondition helper for state.
Show answer Hide answer
check(!isClosed) { "already closed" }require is for arguments; check is for state.
resources and Result
4. Auto-close a resource
Read all text from a reader (an AutoCloseable), making sure it’s closed afterward.
Show answer Hide answer
reader.use { it.readText() }use closes the resource whether the block succeeds or throws — Kotlin’s try-with-resources.
5. Capture success or failure
Use runCatching to parse text to an Int, returning -1 on failure.
Show answer Hide answer
runCatching { text.toInt() }.getOrElse { -1 } 6. A function that always throws
Write fail(message: String) whose return type tells the compiler control never continues past it.
Show answer Hide answer
fun fail(message: String): Nothing = throw IllegalStateException(message)Nothing lets it stand in anywhere — e.g. val x = maybe ?: fail("missing").
the bigger picture
7. No checked exceptions
readFile() can throw IOException. Write a function that calls it and returns the result — with no try/catch and no throws clause.
Show answer Hide answer
fun load(): String {
return readFile() // no catch, no throws — Kotlin has no checked exceptions
} 8. Model errors as data
For a fetch that can fail in an expected way, declare a sealed FetchResult with Success(val user: User) and Error(val message: String) instead of throwing.
Show answer Hide answer
sealed class FetchResult {
data class Success(val user: User) : FetchResult()
data class Error(val message: String) : FetchResult()
}Sealed result types make the failure path part of the return type, checked by an exhaustive when.
9. Get-or-null
Use runCatching to attempt risky() and produce its result or null.
Show answer Hide answer
runCatching { risky() }.getOrNull() 10. Catch is an expression too
Assign config from loadConfig(), falling back to Config.default() if it throws — in one expression.
Show answer Hide answer
val config = try { loadConfig() } catch (e: Exception) { Config.default() } Back to the lesson, Unchecked and Unbothered, or on to the next one: Java interop.
Comments