fujithuro / expensesBook

自分用の家計簿Webアプリケーションです。サーバーサイドはある程度仕上がっていますがフロントは未作成です。
0 stars 0 forks source link

エラー発生時のレスポンス内容について検討する #12

Closed fujithuro closed 2 weeks ago

fujithuro commented 2 weeks ago

現状と課題

入力値検証で例外が発生し、400 Bad Requestを返す場合、そのmessageINFOレベルで記録しているが、 レスポンスボディは空にしている。 受け取った側が分かりやすいように、エラーの概要をメッセージボディで返したい。

なお、単純に例外のmessageを返すだけだと、MethodArgumentNotValidExceptionHttpMessageNotReadableExceptionの場合で内部構造の情報をガッツリ含んだメッセージになってしまう。これはユーザーには見せたくない。

Validation failed for argument [0] in public org.springframework.http.ResponseEntity<com.thurofuji.expensesBook.bean.ExpenseResponse> com.thurofuji.expensesBook.controller.ExpensesBookController.registerExpense(com.thurofuji.expensesBook.bean.ExpenseRequest,org.springframework.security.oauth2.jwt.Jwt): [Field error in object 'expenseRequest' on field 'type': rejected value [null]; codes [NotNull.expenseRequest.type,NotNull.type,NotNull.java.lang.Integer,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [expenseRequest.type,type]; arguments []; default message [type]]; default message [null は許可されていません]]

せめてどのプロパティに問題があったのかだけでも分かるようにしたい。

対応方針

まだNotNullくらいしか使っていないが、Spring Bootではアノテーションを使った入力値検証ができるし、違反した場合のエラーメッセージも設定できる。これらを活用してエラーの概要を返すようにするのがいいのではないか。

fujithuro commented 2 weeks ago

RFC 9457

エラーレスポンスに関する標準がRFC 9457でまとめられている。 (以前はRFC 7807だったが、廃止されている)

RFC 9457 - Problem Details for HTTP APIs 日本語訳 https://tex2e.github.io/rfc-translater/html/rfc9457.html

これにガッツリ準拠する必要まではないのかもしれないが、ちゃんと参考にはしたい

fujithuro commented 2 weeks ago

対応方針の更新

まだNotNullくらいしか使っていないが、Spring Bootではアノテーションを使った入力値検証ができるし、違反した場合のエラーメッセージも設定できる。これらを活用してエラーの概要を返すようにするのがいいのではないか。

つまり@field:NotNull(message = "Date is required.")などを活用することで、簡単にレスポンス作成ができるのではと考えていた。 しかし、おそらくそういうわけにもいかなさそう? 例外ハンドラーに例外発生時の処理を集約する場合、messageに設定した内容は、例外から取得してレスポンスに設定し直す手間が必要。 messageを書いてさえおけば後は良い感じにしてくれる、というようなものではない。

エラーの詳細は、例外が保持している情報から取得できる。 たとえばMethodArgumentNotValidExceptionであればBindingResultから取得でき、 MethodArgumentTypeMismatchExceptionnameから発生元のフィールド、valueから実際渡された値を取得できる。

これらの情報を参照し、要件に合ったロギングやレスポンスの作成を行うのが適切と思われる。

fujithuro commented 2 weeks ago

別ブランチを作らず、コミットメッセージにも参照を書かないまま、このIssueへの対応を進めてしまった。 PRも何もないが、対応完了している