web-dev-qa-db-ja.com

例外のHTTPステータスコード

私はSpringBootコントローラを持っていますが、例外に対して正しいhttpコードステータスを返したいです。だから、私の質問は次のとおりです。「500」または「409」の例外のどちらのhttp statuコードが優れていますか?

これは私のコードです:

@PostMapping(value = {"", "/"})
public ResponseEntity<Response> create(@RequestBody StudioDto studioDto,
        ServletRequest servletRequest, ServletResponse servletResponse) {

    Response response = new Response();

    try {
        studioService.createStudio(studioDto);
        response.setMessage("The studio was create");
        response.setStatusCode(HttpServletResponse.SC_CREATED);

    } catch (Exception e) {
        response.setMessage("Op we have a little problem");
        response.setErrorMessage(e.getMessage());

        //Which one
        //this one 5xx
        response.setStatusCode(500);
        //Or this one 4xx
        response.setStatusCode(409);
    }

    return new ResponseEntity(response, response.getHttpStatus());
}
7
Carlos Mario

これは、例外を処理するための推奨される方法ではありません。コントローラーアドバイスを使用する必要があります。これを確認してください link

ステータスコードは特定のシナリオによって定義されます。500は、原因が特定されていない問題に使用する内部サーバーエラーを意味します。409は、ターゲットリソースでの競合に似ています。

ターゲットリソースの現在の状態と競合するため、要求を完了できませんでした。このコードは、ユーザーが競合を解決してリクエストを再送信できる状況で使用されます

さまざまなケースに適した他の多くのステータスコードがあるので、特定のステータスコードが正しい答えではないと言うでしょう。これを確認できます link 詳細

3
Amer Qarabsa

トッドは素晴らしいリンクをくれました。これはそれについて考えるより良い方法です:

https://httpstatuses.com/

  • 1××情報

  • 2××成功

  • 3××リダイレクト

  • 4××クライアントエラー* 400不正なリクエスト* 401認証されていない... * 405メソッドが許可されていない...

  • 5××サーバーエラー* 500内部サーバーエラー* 501未実装* 502不正なゲートウェイ...

つまり、各メジャー番号(200、400、500など)は[〜#〜] category [〜#〜]です。 「カテゴリ」内の特定のエラーを選択することにより、エラーコードを「洗練」できます。

元の質問へ:

  • クライアントリクエストが「悪い」(たとえば、不正なユーザー名/パスワード)の場合、4xxを返します。

  • Serverが何らかの理由で失敗した場合(たとえば、データベースを読み取れない場合)、5xxを返します。

HTTPエラーコードの「公式」リストはRFC 7231です。

https://tools.ietf.org/html/rfc7231

6
paulsm4

それはあなたが伝えようとしているメッセージに依存します。ステータスコードは、次に何をすべきかについての発信者へのガイダンスと考えてください。ユーザーが何もできないと思われるのが内部サーバーエラーの場合、 a 5 エラーが適切です。

サーバーは、要求の実行を妨げる予期しない状態を検出しました。

一方、 a 409 は、ユーザーが概念的に解決できる競合を示します。

ターゲットリソースの現在の状態と競合するため、要求を完了できませんでした。このコードは、ユーザーが競合を解決してリクエストを再送信できる状況で使用されます。

ほとんどの400レベルのエラーは、ユーザーが理論的には修正して再送信できることを示しています。

個人的には、より正確な例外をキャッチし、それぞれがどのステータスコードを返すかを決定することをお勧めします。これは、ユースケースに本当に依存するためです。現時点では、Exceptionをキャッチしていますが、それはほぼすべての可能性があるため、発信者にどのようなガイダンスを与えるべきかを判断するのは困難です。

2
Todd

5.XXコードはサーバー側からのエラーを意味し、4.XXXコードはクライアント側からのエラーを意味します。
ここで例外をキャッチします。

 catch (Exception e) {
    response.setMessage("Op we have a little problem");
    response.setErrorMessage(e.getMessage());

    //Which one
    //this one 5xx
    response.setStatusCode(500);
    //Or this one 4xx
    response.setStatusCode(409);
}

明らかに不可能です問題がクライアントリクエスト(例:悪いパラメーター)に起因するのか、サーバーエラー(例:DBの不整合またはプログラムエラー)に起因するのかを知ること。

精度4.XXXまたは5.XXXで設定できるようにするために、コードはClientErrorExceptionおよびServerErrorExceptionなどの特定の基本例外に依存できます。

エラーの原因に応じてどちらかをスローすると、それらに依存して正しいステータスコードを設定できます。

try {
    studioService.createStudio(studioDto);
    response.setMessage("The studio was create");
    response.setStatusCode(HttpServletResponse.SC_CREATED);
} 
 catch (ClientErrorException e) {
    response.setStatusCode(409);
}
catch (ServerErrorException e) {
    response.setStatusCode(500);
}

別の方法は、例外ベースクラスにステータスコードフィールドを追加することです。
次のように簡単に書くことができます。

try {
    studioService.createStudio(studioDto);
    response.setMessage("The studio was create");
    response.setStatusCode(HttpServletResponse.SC_CREATED);

} 
 catch (MyRestException e) {
    response.setStatusCode(e.getStatusCode());
}

これらのカスタム例外は、クライアント要求でエラーを検出するとコードから直接スローされる可能性があります(4.XXX)。
この方法では、サーバー処理に関連する他のすべての例外を考慮することができます(5.XXX)。
Spring Exception Handlerはこのタスクを簡単に実行できます。

1
davidxxx