Careeroza
Throwing and Custom Exceptions
throw and Custom Exception Classes
Example
Create your own exception types by extending Exception (or a more specific class). throw is an expression of type Nothing, so it can be used with ?:.
class InsufficientBalanceException(val needed: Double) :
Exception("Insufficient balance: need ${needed} more")
class Account(var balance: Double) {
fun withdraw(amount: Double) {
if (amount > balance) throw InsufficientBalanceException(amount - balance)
balance -= amount
}
}
fun findUser(id: Int): String? = if (id == 1) "Asha" else null
fun main() {
val acc = Account(1000.0)
try {
acc.withdraw(400.0)
acc.withdraw(800.0)
} catch (e: InsufficientBalanceException) {
println(e.message)
println("Shortfall: ${e.needed}")
}
try {
val name = findUser(2) ?: throw IllegalArgumentException("User 2 not found")
println(name)
} catch (e: IllegalArgumentException) {
println("Error: ${e.message}")
}
}Output
Insufficient balance: need 200.0 more Shortfall: 200.0 Error: User 2 not found
require, check and error
The standard library has short helpers for common checks:
| Function | Throws | Use for |
|---|---|---|
require(cond) { msg } | IllegalArgumentException | validating function arguments |
requireNotNull(x) { msg } | IllegalArgumentException | argument must not be null |
check(cond) { msg } | IllegalStateException | validating object state |
error(msg) | IllegalStateException | unreachable / impossible situation |
Example
class Player {
var started = false
fun play(song: String) {
check(started) { "Call start() before play()" }
println("Playing $song")
}
}
fun setVolume(level: Int) {
require(level in 0..100) { "Volume must be 0-100, was $level" }
println("Volume set to $level")
}
fun main() {
setVolume(70)
try { setVolume(150) } catch (e: IllegalArgumentException) { println(e.message) }
try { Player().play("Naatu Naatu") } catch (e: IllegalStateException) { println(e.message) }
}Output
Volume set to 70 Volume must be 0-100, was 150 Call start() before play()