Kotlin Throwing Exceptions | Android Introduction #26
In this reading, you will review the process of throwing and catching exceptions, learn about exception reports and learn to use finally block.
Defining & Throwing Exceptions
Any class that extends Throwable can be used as an exception. That means it can be thrown using a throw block. Such an exception immediately ends functions unless it is caught with a try-catch block.
class MyError: Throwable("Some message")
fun someFunction() {
throw MyError()
println("Will not be printed")
}
fun main() {
try {
someFunction()
println("Will not be printed")
} catch (e: Throwable) {
println("Caught $e") // Caught MyError: Some message
}
}
Exception Report & Stack Trace
When an exception is not caught, it ends the program. As a result, there is printed information about this exception.
class MyError: Throwable("Some message")
fun someFunction() {
throw MyError()
println("Will not be printed")
}
fun main() {
someFunction()
println("Will not be printed")
}
Result:
Exception in thread "main" MyError: Some message
at TestKt.someFunction(Test2.kt:4)
at TestKt.main(Test2.kt:9)
at TestKt.main(Test2.kt)
This information about exceptions, known as an exception report, is really useful.
First, it tells you the type of exception and its message. Message is a parameter from Throwable, that is often specified when you throw an exception. There is also a structure called stack trace, that tells you where this exception was thrown. An exception is thrown in a function, that was invoked in another function, that was invoked in another function and so on. To fully represent that, you should not only show where throw was used, but also where this function was called, and so forth. As a result, you have a whole stack of functions, and for each of them, stack trace prints its name, class, and the line where exception occurred. Reading stack trace is really useful, when you are debugging your program, that is to say, finding and fixing mistakes.
Finally Block
Inside try, you can also use a block called finally. It is used to specify a block of code that should always be invoked, even if an exception occurs.
Take a look at the code below. Inside someFunction an exception is thrown. It ends the function, and it ends the body of try. Since you do not have catch block, this exception will not be caught, and it will end the ‘main’ function. However, there is the finally block that is invoked even if an exception occurs.
fun someFunction() {
throw Throwable("Some error")
println("Will not be printed")
}
fun main() {
try {
someFunction()
println("Will not be printed")
} finally {
println("Finally block was called") // Finally block was called
}
println("Will not be printed")
}
The finally block is also invoked when the try block finishes without an exception.
fun someFunction() {
println("Will be printed") // Will be printed
}
fun main() {
try {
someFunction()
println("Will be printed") // Will be printed
} finally {
println("Finally block was called") // Finally block was called
}
println("Will be printed") // Will be printed
}
finally block is used to do operations that should always be done, no matter if an exception occurred or not. It typically involves closing connections or cleaning-up resources.
Important exceptions
There are a few kinds of exceptions defined in Kotlin that are used in certain situations. The most important ones are:
- IllegalArgumentException — used when an argument has an incorrect value. For example, when you expect your argument value to be bigger than 0, and it is not.
- IllegalStateException — used when the state of our system is incorrect. That means the values of properties have values that are not accepted by our function call.
fun findClusters(number: Int) {
if (number < 1) throw IllegalArgumentException("The number of clusters cannot be smaller than 1, it is $number")
// ...
}
var userName = ""
fun printUserName() {
if (userName == "") throw IllegalStateException("User name must not be empty")
// ...
}
You should now know more about the process of throwing and catching exceptions, appreciate the value of detailed exception reports and know when and why to use finally block. 🎉💯