はじめに
記事を見てくださりありがとうございます!
@HayatoHanaoka と申します。
今回はError
とException
について新しい学びがありました。
java
やkotlin
といったjvm系言語をメインで扱っている人からすると、「当たり前の内容じゃん?」と思うかもしれません。
ただ、筆者は今回のプロジェクトで初めてjvm系言語を扱ったので、新しい学びでした。
備忘録がてら残そうと思います。
何があったのか?
以下のコードを見た社内のとあるエンジニアの方から、とあるご指摘をいただきました。
example.kt
class ExampleUseCase(private val examplePort: ExamplePort) {
fun example(resouceId: ResourceId): Resource {
// リソースを取得しにいき、なければエラーとする
val result = examplePort.getResource(resourceId) ?: throw Error("Couldn't get resource")
return Resource(result)
}
}
👨 「どうしてエラーを投げてるの?」
👨 「ここで起こるのは、リソースが取れなかった という 例外 だよね」
これを聞いた時、恥ずかしながら「え?何が違うんだ...?」となってしまいました。
皆さんはこの違いを認識できますか...?
何がよくなかったのか?
jvm系の言語は、以下の階層構造でthrowable
を持っています。
この違いを全く認識しておらず、今回は処理上発生するエラーに Error
を割り当ててしまっていたのがよくなかったのですね。
どう修正するのが適切か?
これを踏まえてコードを修正すると、以下のようになります。
class ExampleUseCase(private val examplePort: ExamplePort) {
fun example(resourceId: ResourceId): : Resource {
// リソースを取得しにいき、なければエラーとする
- val result = examplePort.getResource(resourceId) ?: throw Error("Couldn't get resource")
+ val result = examplePort.getResource(resourceId) ?: throw IllegalArgumentException("IllegalArgumentException: $resourceId is illegal")
return Resource(result)
}
}
最後に
適切なエラーや例外をハンドリングして返すことは意外と難しい。
エラーハンドリングの際は、公式Docs等でエラーの種類などを事前に調査して、適切に扱えるよう注意しようと思います。