📑
Kotlinの関数型エラーハンドリング例
この記事は、自分の技術メモをAIで記事化しているため、一部間違いが含まれている可能性があります。ご了承ください!
Kotlinの関数型エラーハンドリングについて、実践的なコード例を交えながら解説します。本記事では、特にエラー定義や初期化時の注意点について掘り下げていきます。
💡 エラーハンドリングの基本構造
Kotlinでは、関数型のアプローチでエラーを扱うことができます。エラー定義に情報を付加することで、エラーメッセージの管理が楽になります。
エラー定義のポイント
-
エラーメッセージをメソッド化する
毎回エラーメッセージを手動で組み立てるのは非効率です。メソッドにして再利用性を高めましょう。
-
エラー情報を付加する
エラーの種類に応じて、追加の情報(例: サイズなど)を持たせると便利です。
以下のコード例では、CommentBodyFailure
というエラー定義を作成しています。
package com.example.comment
import com.example.util.Result
import com.example.util.Result.Success
import com.example.util.Result.Failure
sealed interface CommentBodyFailure {
// 毎回エラーメッセージを組み立てるのは無駄なので、メソッドにしておく
fun errorMessage(): String
data class TooLarge(val actualSize: Int) : CommentBodyFailure {
override fun errorMessage() = "Too large for $actualSize"
}
data class TooSmall(val actualSize: Int) : CommentBodyFailure {
override fun errorMessage() = "Too small for $actualSize"
}
}
🛠️ データクラスと初期化処理の注意点
データクラスにおける初期化処理では、不変条件を守るためにinit
ブロックを利用します。ただし、constructor
を公開しておくことで初期化テストがしやすくなります。
初期化時の注意点
-
不変条件の記述
init
ブロックでデータの妥当性をチェックします。 -
テストの重複
constructor
とvalidate
関数の両方でテストが必要になる点に注意。
以下は、CommentBody
クラスの例です。
data class CommentBody constructor(private val value: String) {
init {
// 不変条件としてinitも書いておく
// デメリットとしては、constructorとvalidate関数のテストが重複して必要になること
validate(value)?.let {
// 特に種別ごとにハンドリングする必要ないなら、これでいい
// ハンドリングしたいならwhenを使ってハンドリングすると良さそう
throw IllegalArgumentException(it.errorMessage())
}
}
companion object {
const val MAX_LENGTH = 100_000
const val MIN_LENGTH = 1
private fun validate(value: String): CommentBodyFailure? {
val length = value.length
if (length < MIN_LENGTH) {
return CommentBodyFailure.TooSmall(actualSize = length)
}
if (length > MAX_LENGTH) {
return CommentBodyFailure.TooLarge(actualSize = length)
}
return null
}
fun create(value: String): Result<CommentBody, CommentBodyFailure> =
validate(value)
?.let { Failure(it) }
?: Success(CommentBody(value))
}
}
📌 実装時のポイント
-
エラーハンドリングの簡略化
エラー種別ごとに個別対応が不要なら、そのままスローする設計が有効です。
-
再利用性の高い設計
バリデーション処理を
companion object
に切り出すことで、簡単に再利用できます。
Kotlinを使った関数型エラーハンドリングの基本構造を理解することで、より堅牢でメンテナンス性の高いコードを書くことができます。今回のコード例を参考に、ぜひ実践で試してみてください!
Discussion