web-dev-qa-db-ja.com

SpringのHttpClientErrorExceptionが未チェックの例外であるのはなぜですか?

Oracle 未チェックの例外の目的を要約

次の質問は、「メソッドのAPIをドキュメント化するのが良い場合は(スローできる例外も含む)、ランタイム例外も指定しないのはなぜですか?」ランタイム例外は、プログラミングの問題の結果である問題を表します。そのため、APIクライアントコードは、例外から回復したり、何らかの方法で処理したりすることは合理的に期待できません。このような問題には、ゼロによる除算などの算術例外が含まれます。 null参照を介してオブジェクトにアクセスしようとするなどのポインタ例外。インデックス付けの例外。たとえば、大きすぎるまたは小さすぎるインデックスを使用して配列要素にアクセスしようとした場合。

OK、チェックされていない例外は、プログラマーのエラーが原因のエラーです。承知しました。

Springの HttpClientErrorExceptionのドキュメント (RuntimeExceptionを拡張)は、例外は次のように述べています。

HTTP 4xxを受信したときにスローされる例外。

これが「プログラマエラー」の例外であることはわかりません。

私がテストしているシナリオでは、Spring RestTemplateにクエリを作成していますが、クエリを実行しているサーバーがダウンし、404を返す場合があります。これは、プログラミングエラーではなく、まったく正常な状態のようです。

私はおそらくSpring Frameworkと正しく対話していないのですか(つまり、RestTemplateを使用する前に404を検出する必要がありますか)、それとも他に考慮していないことはありますか?

4
dwjohnston

お元気ですか。

この観点から見てください。 未チェックの例外-論争

クライアントが例外からの回復が合理的に期待できる場合は、チェック済み例外にします。クライアントが例外から回復するために何もできない場合は、チェックされていない例外にします。

上記の前提によるハンディキャップです。 Spring Rest Clientは404からの回復を期待していないため、上位層でエラーをキャッチして処理するという決定を利用します。外部サービスへの接続が4xxまたは5xxエラーで終了したときに何をするかを決定するのは、システムの責任です。不要なtry/catch/final blocksを使用してSpring Web全体とコアアーキテクチャを危険にさらさず、メソッドのシグネチャにthrowを追加して無数のコンポーネントをリファクタリングする方法は、RuntimeExceptions

その結果、Springユーザーがそのような事態に関与します。 気をつけて、そのようなエラーから回復するか、それを次のレイヤーに(彼らがするように)手放すように、私たちに春の委任をしてください...など...

あなたの質問に

すなわち。 RestTemplateを使用する前に404を検出する必要がありますか?

このようなエラーから回復できるかどうかによって異なります。あなたはできる?外部サービスが利用できない場合に何かすることはありますか?その場合は、catchHttpClientErrorExceptionを使用します。そうでない場合は、おそらくログに記録し、サービスまたはビジネスの例外にラップしてクライアントに要求の失敗に関する詳細情報を提供するために、とにかくそれをキャッチするでしょう。 どこで発生したか、なぜ発生したか、何をすべきかなど

他の人がすることに関係なく、Springでは ErrorHandlers を使用して応答エラーを適切に処理できます。または、メソッドを上書きするには handleResponse

4
Laiv

Springが404を「回復不能」シナリオと見なしたと想定しています。

「404からの回復」の概念は、Oracleが意味する "と一致していないと思います回復可能」

Oracleの「回復不能」 は、たわごとが深刻に間違ったことを意味します。 NullPointerExceptionなどと同様。ソースコードのバグのように。ここで、チェックされていない例外が発生します。

私の理解では、すべてのHTTPコードはHTTP仕様の有効なシナリオと見なされます。それらは文書化され、予期されており、既知の緩和策があります。

春はこれの反対側にあると思います。

たとえば、RestTemplate#doExecuteは、httpクライアントのチェックされた例外をチェックされていない例外にラップします。これは悪いです...


私は現在、非常によく似た問題に直面しています。

非常に具体的な例外をスローするカスタムResponseErrorHandlerを作成する必要があります(これは、インターフェイスのシグネチャにあるため、IOExceptionを拡張する可能性があります)。

次に、RestTemplateは、チェックされていない例外でIOExceptionをラップすることにより、これを非表示にします。

説明を与えるのは、Nice of Springです。それがない場合は、これを修正してください。

0