Java の例外に対処するための最も慣用的な方法が1 つあるかどうかはわかりません。例外がスローされるケースが少なくとも 4 つあります。
- あなたもライブラリの設計者も、うまくいかないとは本当に思っていなかった何かがうまくいかなかったのです。
- ライブラリの設計者が望んでいた機能が機能しなかったため、詳細を知る必要があります。
- うまくいくと思っていたことがうまくいきませんでした。詳細を知る必要はありません。
- メソッドは値を生成する場合と生成しない場合があり、例外をスローすることでそれを伝えます。
ベスト プラクティスは、これらのケースごとにほぼ間違いなく異なります。
1. 本当に例外的な例外
Scala には完全な機能の例外処理機能があります。何らかの対処ができるレベルになるまで、予期しない例外がキャッチされずに伝播するのを放置しても問題はありません。考えられるすべての例外をEither
缶にパッケージ化すると、多くの時間が無駄になります。処理していないことがわかっていることを文書化し、適切な高レベルで try/catch を使用します (たとえば、saveEverything
メソッドはおそらく try/catch ブロックに入れる (またはその内容を 1 つにラップする) 必要があります。すべてを保存するのに失敗した場合は、単に死ぬだけでなく、状況を救おうとする可能性があります)。
特に、おそらくこの方法で処理し、すべての ではなくError
のみを にパッケージ化する必要があります。Exception
Throwable
Either
2. 知っておくべき例外
これはあなたが話しているケースであり、それらに対処する方法についてすでにいくつかの良い提案をしています。catching
既にお気付きのように、 を使用して例外を にパッケージ化できますEither
。その後、次のこともできます
a. Either
パターン マッチングを使用すると、より深く分解できます。
doesNotThrowExceptions("par").right.map(transformData) match {
case Left(ioe: IOException) => /* ... */
case Left(nsae: NoSuchAlgorithmException) => /* ... */
case Right(x) => /* ... */
case Left(e) => throw e // Didn't expect this one...
}
b. Option
エラーをログに記録した後にダウンコンバートします。
doesNotThrowExceptions("par").left.map{ e =>
println("You're not going to like this, but something bad happened:")
println(e)
println("Let's see if we can still make this work....")
}.right.toOption
c. 例外がフロー制御の非常に重要な部分であるEither
場合、十分ではない可能性があります。代わりに、 and以外のものを使用して、独自の のEither
ようなクラスを定義したい場合があります。または、次の左側をネストできます。Left
Right
Either
try { Right(/* java code */) }
catch {
case ioe: IOException => Left(Left(ioe))
case nsae: NoSuchAlgorithmException => Left(Right(nsae))
}
d. ScalazValidation
を使用します。これはよく似Either
ていますが、もう少し例外処理に合わせて調整されています。
3. 何かがうまくいかなかったことだけを知る必要がある例外
4. 戻り値がないことを示すためにスローされる例外
これらは概念的には 2 つの異なるカテゴリですが、同じ方法で処理します。
catching(classOf[IOException], classOf[NoSuchAlgorithmException]) opt { ... }
バックを取得しOption
ます。次に、、、map
などflatMap
。