try, catch, finally
In this page:
try {
// risky code
} catch (e: ExceptionType) {
// handle it
} catch (e: OtherException) {
// handle differently
} finally {
// always runs
}
Catching an Exception
Wrapping risky code in try { } followed by catch (e: ExceptionType) { } lets the program recover gracefully instead of crashing when that specific kind of exception occurs.
Example: Catching an Exception
// Entry point: execution of the program starts here
fun main() {
try {
// Declare a read-only variable `result`, set to `10 / 0`
val result = 10 / 0
// Print `result` to the console, with a trailing newline
println(result)
} catch (e: ArithmeticException) {
// Print "Caught an error: ${e.message}" to the console, with a trailing newline
println("Caught an error: ${e.message}")
}
}
Login to try C/C++/Java/PHP code in the editor
Using finally for Cleanup
A finally { } block always executes after the try/catch, regardless of whether an exception was thrown or caught, making it the right place for cleanup code that must always run.
Example: Using finally for Cleanup
// Entry point: execution of the program starts here
fun main() {
try {
// Print "Attempting risky operation" to the console, with a trailing newline
println("Attempting risky operation")
throw RuntimeException("Something failed")
} catch (e: RuntimeException) {
// Print "Handled: ${e.message}" to the console, with a trailing newline
println("Handled: ${e.message}")
} finally {
// Print "Cleanup always runs" to the console, with a trailing newline
println("Cleanup always runs")
}
}
Login to try C/C++/Java/PHP code in the editor
Multiple catch Blocks
Several catch blocks can be chained to handle different exception types differently, and Kotlin checks them in the order they are written, using the first matching type.
Example: Multiple catch Blocks
// Entry point: execution of the program starts here
fun main() {
// Declare a read-only variable `values`, set to `listOf("10", "abc", "5")`
val values = listOf("10", "abc", "5")
// Loop over `values`, binding each item to `value`
for (value in values) {
try {
// Print "Parsed: ${value.toInt()}" to the console, with a trailing newline
println("Parsed: ${value.toInt()}")
} catch (e: NumberFormatException) {
// Print "Not a number: $value" to the console, with a trailing newline
println("Not a number: $value")
}
}
}
Login to try C/C++/Java/PHP code in the editor
try as an Expression
Because try can be used as an expression, the value from whichever branch executes -- try or catch -- can be assigned directly to a variable.
Example: try as an Expression
// Define the function `parseOrDefault` taking `text` and returning an Int
fun parseOrDefault(text: String): Int {
// Return `try {` from this function
return try {
text.toInt()
} catch (e: NumberFormatException) {
-1
}
}
// Entry point: execution of the program starts here
fun main() {
// Print `parseOrDefault("42")` to the console, with a trailing newline
println(parseOrDefault("42"))
// Print `parseOrDefault("oops")` to the console, with a trailing newline
println(parseOrDefault("oops"))
}
Login to try C/C++/Java/PHP code in the editor
- Catching a very broad type like
Exceptioneverywhere, hiding bugs that should have been fixed rather than silently swallowed. - Forgetting that
finallyalways runs, even if thetryorcatchblock returns early, which is exactly the point of using it for cleanup. - Not realizing
trycan be used as an expression, producing a value from whichever branch actually ran.
try { }wraps code that might throw an exception;catch (e: Type) { }handles a specific exception type if one occurs.finally { }always runs after the try/catch, whether or not an exception was thrown, making it ideal for cleanup.- Multiple
catchblocks can handle different exception types differently, checked in order from top to bottom. trycan be used as an expression, with the resulting value coming from whichever branch (try or catch) actually executed.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: