カスタム例外クラスの作成
意味のあるメッセージとプロパティを持つ、ドメイン固有の例外を定義します。
「カスタム例外クラスの作成」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
カスタム例外を使う理由
カスタム例外はドメイン上の意味を表します。呼び出し側は特定の例外だけを捕捉し、有用なメッセージを取得して、型に応じた異なる処理を実行できます。
最も簡単なカスタム例外
Exception(またはRuntimeExceptionのような特定のサブクラス)を継承し、スーパークラスのコンストラクターにメッセージを渡します。
class InvalidEmailException(message: String) : Exception(message)
fun main() {
try {
throw InvalidEmailException("missing @")
} catch (e: InvalidEmailException) {
println("caught: ${e.message}")
}
}プロパティを持つ例外
HTTPステータス、フィールド名、再試行回数などのフィールドを追加して、コンテキストを伝えます。
class HttpError(
message: String,
val statusCode: Int
) : Exception(message)
fun main() {
try {
throw HttpError("Not Found", 404)
} catch (e: HttpError) {
println("HTTP ${e.statusCode}: ${e.message}")
}
}原因を持つ例外
causeを渡して、元の例外をチェーン内に保持します。
class DatabaseError(message: String, cause: Throwable) : Exception(message, cause)
fun main() {
try {
try { error("connection refused") }
catch (e: Throwable) { throw DatabaseError("query failed", e) }
} catch (e: DatabaseError) {
println("${e.message} (caused by: ${e.cause?.message})")
}
}検査例外と非検査例外
Kotlinでは、すべての例外が非検査例外として扱われるため、throws宣言は必要ありません。慣例としてRuntimeExceptionを継承します。
class ValidationException(field: String, message: String) :
RuntimeException("[$field] $message")
fun main() {
try {
throw ValidationException("age", "must be positive")
} catch (e: ValidationException) {
println(e.message)
}
}ドメイン例外の階層
階層を構築すると、呼び出し側は一般的な処理には基底型を、特別なケースには特定のサブタイプを捕捉できます。
open class AppException(message: String) : RuntimeException(message)
class NotFoundException(what: String) : AppException("$what not found")
class UnauthorizedException : AppException("not authorized")
fun main() {
val errors = listOf(NotFoundException("user"), UnauthorizedException())
for (e in errors) {
try { throw e }
catch (e: AppException) { println("App error: ${e.message}") }
}
}sealed例外階層
エラー型の集合が限定されている場合は、sealed階層を使用します。呼び出し側で、すべてのバリエーションを網羅的に処理できます。
sealed class ApiError(message: String) : RuntimeException(message) {
class Timeout : ApiError("timeout")
class NotFound(val id: String) : ApiError("not found: $id")
class ServerError(val status: Int) : ApiError("server returned $status")
}
fun describe(e: ApiError) = when (e) {
is ApiError.Timeout -> "request timed out"
is ApiError.NotFound -> "id ${e.id} missing"
is ApiError.ServerError -> "5xx: ${e.status}"
}
fun main() {
println(describe(ApiError.NotFound("user-42")))
}命名規則
明確さを保つため、カスタム例外クラスの名前はExceptionまたはErrorで終わらせます。過去形または名詞を使用します(例:NotFound、InvalidInput)。
class InvalidInputException(msg: String) : RuntimeException(msg)
class UserNotFoundException(id: Int) : RuntimeException("user $id not found")
fun main() {
try { throw UserNotFoundException(7) }
catch (e: UserNotFoundException) { println(e.message) }
}例外のドキュメント化
KDocの@throwsを使用して、関数がスローする可能性のある例外を記述します。
/**
* @throws InvalidEmailException if the email is malformed
*/
fun validate(email: String) {
if ("@" !in email) throw InvalidEmailException("missing @")
}
class InvalidEmailException(m: String) : RuntimeException(m)
fun main() {
try { validate("nope") }
catch (e: InvalidEmailException) { println(e.message) }
}例外の過剰使用を避ける
例外は例外的な状況に使用します。空の入力や任意フィールドの欠落など、予想される結果には、nullableな戻り値、sealedな結果型、またはデフォルト値を使用してください。
fun findUser(id: Int): String? = if (id == 1) "Alice" else null
fun main() {
val name = findUser(42) ?: "(unknown)"
println(name) // (unknown), no exception
}実践例
ステータスとボディを持つ、架空のAPIクライアント向けの現実的なカスタム例外です。
class ApiException(
message: String,
val statusCode: Int,
val responseBody: String
) : RuntimeException(message)
fun main() {
try {
throw ApiException("Bad Request", 400, "{\"error\":\"invalid\"}")
} catch (e: ApiException) {
println("[${e.statusCode}] ${e.message}: ${e.responseBody}")
}
}クイックチェック
ドメイン固有のKotlin例外を定義するとき、最も一般的に使用される親クラスは何ですか。
まとめ
カスタム例外はドメイン上の意味を表します。RuntimeExceptionまたはExceptionを継承し、コンテキスト用のプロパティを追加し、原因を保持し、グループ化したcatchのために階層を構築します。エラー型が限定されている場合はsealed例外を使用し、エラーが予想される場合はnullable型やresult型を優先してください。
よくある質問
「カスタム例外クラスの作成」レッスンは無料ですか?
はい。「カスタム例外クラスの作成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「カスタム例外クラスの作成」で何を学びますか?
意味のあるメッセージとプロパティを持つ、ドメイン固有の例外を定義します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「カスタム例外クラスの作成」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。