例外の粒度


9

私は、次のような彼らは、一般的な例外を好む数人の友人とI.間の論争に実行したClientErrorExceptionServerErrorException私は物事にもっと具体的に作ることを好むのに対し、例外のフィールドとして詳細に。たとえば、次のような例外がいくつかある場合があります。

  • BadRequestException
  • AuthenticationFailureException
  • ProductNotFoundException

これらはそれぞれ、APIから返されたエラーコードに基づいて構築されています。

例外の利点に従うとこれはJavaにとって慣用的なようです。しかし、私の友人の意見は全く珍しいことではありません。

コードの読みやすさとAPIの使いやすさの点で好ましい方法はありますか、それとも本当に好みに帰着するだけですか?


あなたがリンクしたページは、おそらく私たちが得ることができる最も確実な答えです。あなたは本当に意見を求めています。私の経験や意見についてはお答えできますが、それは客観的な答えではありません。
marstato 2018年

@marstatoそれは公正です。私は自分の立場で正当化を求めていると思います。私が書いたライブラリーで人々が期待していることを守りたいと思います。それが私のものを使いやすくするという意味でガイドに従うのではなく、あなたは知っていますか?

私は完全に同意します。例外クラスも細かくしています。また、abstractgetterメソッドを使用して例外クラスを定義および一般化し、詳細なクラスで一般的なクラスを拡張することもできます。例えばAuthenticationFaliureException extends ClientErrorException。このようにして、すべてのユーザーが例外の処理方法を選択できます。もちろん、もっと機能します。ただし、(ライブラリではなく)アプリケーションを作成する場合、それは私見では別の状況です。その場合は、単純にするために、例外を必要以上に細かくしません。
marstato

@marstatoが実際に実装する方法です。同意してくれてうれしいです。質問は一晩中開いたままにしておきますが、少なくともグリーンチェックできるように、それを投稿にまとめてください

回答:


15

多くの異なる例外クラスがあることと、エラーテキストに詳細な情報が含まれる少数の例外クラスがあることの主な違いは、たとえば、多くの異なる例外クラスは、呼び出しコードが異なる種類のエラーに異なる反応をすることを可能にしますが、いくつかのクラスのみで、あらゆる種類の例外を統一された方法で処理することが容易になります。

これは通常、トレードオフです。継承を使用することである程度軽減できます(すべてを包括的にキャッチしてログに記録したい呼び出し元の一般的な基本例外クラス、および異なる反応が必要な呼び出し元のこれらの基本クラスから派生した例外)。注意せずにYAGNIの原則に固執しないと、多くの不必要な複雑さが生じます。したがって、ガイドとなる質問は次のとおりです。

  • コードの呼び出し元が、これらの異なる種類のエラーに対して異なる制御フローで異なる反応をすることを本当に期待していますか?

これには万能のソリューションはなく、どこにでも適用できる頭の痛い「ベストプラクティス」はありません。この質問に対する答えは、設計しているソフトウェアまたはコンポーネントの種類に大きく依存します。

  • あなたやチームがコードベース全体を管理しているアプリケーションがありますか?

  • または、すべての潜在的な呼び出し元を知らないサードパーティ向けの再利用可能なコンポーネントですか?

  • 実行時間の長いサーバーアプリケーション。さまざまな種類のエラーによってシステム全体がすぐに破損することはなく、さまざまな種類のエラーの軽減が必要になる場合があります。

  • エラーが発生した場合にユーザーにエラーメッセージを表示し、プロセスを再起動するだけで十分な、短命のアプリケーションプロセス?

そのため、コンポーネントの潜在的な呼び出し元について知っているほど、例外の正確な詳細レベルをより適切に決定できます。


3
「コードの呼び出し元が、これらの異なる種類のエラーに対して、異なる制御フローで異なる反応をすることを本当に期待していますか?」これは質問するのに最適な質問です。ありがとう、覚えておきます。

これは良い答えだと思います。クライアントアプリケーションに例外をスローする設計を推進させる必要性をさらに強調するだけです。例外階層に組み込むのが賢明だと思われる一般化でさえ、クライアントアプリケーション(自分で記述していない場合)がハンドラーの一般化を選択する方法と一致しない場合があります。ニーズが異なる複数のクライアントアプリケーションがある場合は、当然、それらのバランスを調整する必要があります。
magicduncan

1

答えは、私たちが話しているエラー報告のレベルによって異なります。

一般的に私はあなたの友人に同意します、あなたは彼らに問題の原因を伝えるために必要以上にきめ細かくすべきではありません。

nullを参照する一般的なよく知られた例外(NullReferenceException)がある場合は、独自のMyObjectIsNullExceptionを作成しないでください。それは単に人間の通訳に混乱の層を追加するだけで、何も明確化しないことを学ぶための追加の事柄です。

例外が特別で、根本的な原因をカバーする事前定義されたものがない場合のみ、独自に作成する必要があります。

ただし、そこで停止する必要はありません。一般的なエラーがあなたの構成要素の一つで発生する可能性があり、あなたは問題があった伝えたいことがあり、あなたのコンポーネントでは。何が問題だったのかだけでなく、どこで問題が発生したのか。次に、最初の例外をMyComponentExceptionでラップするのが適切です。それはあなたに両方の世界のベストを与えるでしょう。

まず、コンポーネントが問題に遭遇したことが明らかになります。より低いレバーでは、特定の原因は内部の例外になります。


それは公正です。それで、良い例外がすでに存在するときに、新しい例外を発明しないことを提案しているのですか?

@recはい。定義済みのものは誰もがすでに知っているためです。それが彼らの目的です。
Martin Maat
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.