Kotlin’s try-catch construct protects code that may fail, handles selected exceptions, and can run cleanup in finally. Unlike Java, Kotlin does not require a throws clause or distinguish checked from unchecked exceptions, so you choose which failures to handle. section 2.5.1
Recovering from invalid input
fun readNumber(reader: BufferedReader): Int? { try { val line = reader.readLine() return Integer.parseInt(line) } catch (e: NumberFormatException) { return null } finally { reader.close() } } The protected block reads and parses a line, catch converts invalid input into null, and finally closes the reader regardless of success or failure. section 2.5.1
try is also an expression. The last expression in the try block supplies the result when execution succeeds; the last expression in a matching catch block supplies the fallback result. A catch block may instead return from the enclosing function. section 2.5.2
Assigning a fallback value
val number = try { Integer.parseInt(reader.readLine()) } catch (e: NumberFormatException) { null } println(number) // null This form avoids an intermediate variable while making the failure value explicit. section 2.5.2
Place the handler where the exception is produced:
- Inside launch, try-catch can handle an exception thrown by that coroutine; surrounding launch does not catch exceptions crossing the coroutine boundary. section 18.1
- For async, await rethrows the deferred exception, so surround await with try-catch when the caller must handle the failure. section 18.1
- For Flow, the catch operator handles upstream failures; wrap collect or place handling downstream when the failure occurs there. section 18.4.1
Listing 2.28 Using try the same way you would in Java
import java.io.BufferedReader
import java.io.StringReader
fun readNumber(reader: BufferedReader): Int? { #1
try {
val line = reader.readLine()
return Integer.parseInt(line)
} catch (e: NumberFormatException) { #2
return null
} finally { #3
reader.close()
}
}
fun main() {
val reader = BufferedReader(StringReader("239"))
println(readNumber(reader))
// 239
}
Inspect the complete reader example, including parsing, typed catching, nullable recovery, and resource cleanup. section 2.5.1
Listing 18.1 An async coroutine that throws an exception
import kotlinx.coroutines.*
fun main(): Unit = runBlocking {
val myDeferredInt: Deferred<Int> = async {
throw UnsupportedOperationException("Ouch!")
}
try {
val i: Int = myDeferredInt.await()
println(i)
} catch (u: UnsupportedOperationException) {
println("Handled: $u")
}
}
Compare exception handling around await with handling placed inside a coroutine body. section 18.1









