// Created on savesnippets.com ยท https://savesnippets.com/58JKg4Jrjram24 sealed class AppError(message: String) : Exception(message) { class NotFound(resource: String, id: Any) : AppError("$resource not found: $id") class InvalidInput(field: String, why: String) : AppError("invalid $field: $why") class Unauthorized(msg: String = "unauthorized") : AppError(msg) class Conflict(what: String) : AppError("$what already exists") } interface UserRepo { fun find(id: Int): String } class UserService(private val repo: UserRepo) { fun greet(id: Int): String { if (id <= 0) throw AppError.InvalidInput("id", "must be positive") return runCatching { repo.find(id) } .getOrElse { throw AppError.NotFound("user", id) } } } fun handle(action: () -> Unit) { try { action() } catch (e: AppError) { when (e) { is AppError.NotFound -> println("404: ${e.message}") is AppError.InvalidInput -> println("400: ${e.message}") is AppError.Unauthorized -> println("401: ${e.message}") is AppError.Conflict -> println("409: ${e.message}") } } }