Kotlin
Error handling
Add error handling with try/catch.
Custom error: TaskNotFound
In this project we define a custom exception called TaskNotFound for invalid indexes. The error type then states the cause clearly.
class TaskNotFound(message: String) : Exception(message)
throw TaskNotFound("Task not found: 5")
The class inherits from Exception and passes the message via the constructor. When caught, e.message gives meaningful content. A custom type makes both catching and debugging easier.
The complete method and try/catch
The complete(index) method completes the task at the given index. If the index is past the list, it throws TaskNotFound; the caller catches it with try/catch.
fun complete(index: Int) {
if (index >= tasks.size)
throw TaskNotFound("Task not found: $index")
tasks[index].done = true
}
try {
list.complete(5)
} catch (e: TaskNotFound) {
println(e.message)
}
The bound check happens before the throw. tasks.size gives the list length; an index equal to or beyond it is out of bounds. catch (e: TaskNotFound) catches only this type.
Exercise Add the complete method and try/catch
Add fun complete(index: Int) to the TaskList class: if the index is greater than or equal to tasks.size, throw TaskNotFound("Task not found: $index"); otherwise set tasks[index].done = true. In main add a task, call list.complete(5); catch TaskNotFound with try/catch and print e.message.
Show example solution
class Task(val title: String) {
var done: Boolean = false
override fun toString(): String {
return if (done) "[x] $title" else "[ ] $title"
}
}
class TaskNotFound(message: String) : Exception(message)
class TaskList {
val tasks = mutableListOf<Task>()
fun addTask(title: String) {
tasks.add(Task(title))
}
fun listDone() = tasks.filter { it.done }
fun complete(index: Int) {
if (index >= tasks.size) throw TaskNotFound("Task not found: $index")
tasks[index].done = true
}
}
fun main() {
val list = TaskList()
list.addTask("Study Kotlin")
try {
list.complete(5)
} catch (e: TaskNotFound) {
println(e.message)
}
}
Test yourself
-
Fill in the blank: declare TaskNotFound
class TaskNotFound(message: String) : ____(message)
Show answer
class TaskNotFound(message: String) : Exception(message)
-
Why define a custom exception?
- Less code
- For more meaningful error types
- Less memory
- Speed
Show answer
For more meaningful error types — Application-specific error types are more meaningful.
-
Match piece to role
- class TaskNotFound
- Error class
- : Exception
- Superclass
- throw TaskNotFound
- Throwing
- catch (e: TaskNotFound)
- Catching
Next lesson: Putting it together