LoginSignup
6
8

More than 3 years have passed since last update.

Spring Boot 2.3 からデフォルトのエラーページに詳細なエラー情報が含まれなくなった

Last updated at Posted at 2020-07-19

概要

  • Spring Boot 2.3 から、デフォルトのエラーレスポンス (エラーページ HTML とエラー JSON)に、エラーメッセージやバインディングエラーが含まれなくなった。これは意図しないエラー情報をレスポンスで返さないための措置。
  • プロパティ値を設定することでエラー情報を出力する・出力しないを制御できる。

エラーページ HTML やエラー JSON に出力される項目

DefaultErrorAttributes (Spring Boot 2.3.0.RELEASE API) 等に出力される項目が記載されている。

  • timestamp: エラーが抽出された時間
  • status: ステータスコード
  • error: エラーの理由
  • exception: ルート例外のクラス名
  • message: 例外メッセージ
  • errors: BindingResult にセットされている複数の ObjectError (binding-errors)
  • trace: 例外のスタックトレース
  • path: 例外が発生したときの URL パス

設定用プロパティ

application.properties 等で server.error.include-message (message) や server.error.include-binding-errors の値を設定することによって出力の有無を制御できる。

Spring Boot 2.3 Release Notes · spring-projects/spring-boot Wiki · GitHub

Changes to the Default Error Page’s Content
The error message and any binding errors are no longer included in the default error page by default. This reduces the risk of leaking information to a client. server.error.include-message and server.error.include-binding-errors can be used to control the inclusion of the message and binding errors respectively. Supported values are always, on-param, and never.

  • server.error.include-message (message 項目の出力を制御)
  • server.error.include-binding-errors (errors 項目の出力を制御)
  • server.error.include-stacktrace (trace 項目の出力を制御)
  • server.error.include-exception (exception 項目の出力を制御)

エラー出力例

いくつかの設定パターンによるエラーレスポンスの例を挙げる。
挙げている HTML や JSON は見やすくするために整形したものを載せている。

Spring Boot 2.2

application.properties に何も指定しない場合。
Spring Boot 2.2 では何を指定しなくても message や errors が出力されてしまう。

JSON

{
  "timestamp": "2020-07-19T06:14:27.622+0000",
  "status": 400,
  "error": "Bad Request",
  "errors": [
    {
      "codes": null,
      "arguments": null,
      "defaultMessage": "人為的に発生させたfooエラー",
      "objectName": "fooError",
      "code": null
    },
    {
      "codes": null,
      "arguments": null,
      "defaultMessage": "人為的に発生させたbarエラー",
      "objectName": "barError",
      "code": null
    }
  ],
  "message": "Validation failed for object='fooBarData'. Error count: 2",
  "path": "/json"
}

HTML

<html><body>
<h1>Whitelabel Error Page</h1>
<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>
<div id='created'>Sun Jul 19 15:14:30 JST 2020</div>
<div>There was an unexpected error (type=Bad Request, status=400).</div>
<div>Validation failed for object=&#39;fooBarData&#39;. Error count: 2</div>
</body></html>

Spring Boot 2.3

application.properties に何も指定しない場合。
詳細なエラー情報を出力しない設定となる。

JSON

{
  "timestamp": "2020-07-19T06:13:46.546+00:00",
  "status": 400,
  "error": "Bad Request",
  "message": "",
  "path": "/json"
}

HTML

<html><body>
<h1>Whitelabel Error Page</h1>
<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>
<div id='created'>Sun Jul 19 15:13:48 JST 2020</div>
<div>There was an unexpected error (type=Bad Request, status=400).</div>
<div></div>
</body></html>

Spring Boot 2.3 + プロパティ設定に never, false 指定

application.properties に以下を指定する場合。
詳細なエラー情報を出力しない設定となる。

server.error.include-message=never
server.error.include-binding-errors=never
server.error.include-stacktrace=never
server.error.include-exception=false

JSON

{
  "timestamp": "2020-07-19T06:13:18.720+00:00",
  "status": 400,
  "error": "Bad Request",
  "message": "",
  "path": "/json"
}

HTML

<html><body>
<h1>Whitelabel Error Page</h1>
<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>
<div id='created'>Sun Jul 19 15:13:22 JST 2020</div>
<div>There was an unexpected error (type=Bad Request, status=400).</div>
<div></div>
</body></html>

Spring Boot 2.3 + プロパティ設定に always, true 指定

application.properties に以下を指定する場合。
詳細なエラー情報を出力する設定となる。

server.error.include-message=always
server.error.include-binding-errors=always
server.error.include-stacktrace=always
server.error.include-exception=true

JSON

{
  "timestamp": "2020-07-19T06:11:54.165+00:00",
  "status": 400,
  "error": "Bad Request",
  "exception": "org.springframework.validation.BindException",
  "trace": "org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors\n
            Error in object 'fooError': codes []; arguments []; default message [人為的に発生させたfooエラー]\n
            Error in object 'barError': codes []; arguments []; default message [人為的に発生させたbarエラー]\n\t
            at example.FooBarRestController.json(FooBarRestController.java:20)
            (中略)
            java.base/java.lang.Thread.run(Thread.java:832)\n",
  "message": "Validation failed for object='fooBarData'. Error count: 2",
  "errors": [
    {
      "codes": null,
      "arguments": null,
      "defaultMessage": "人為的に発生させたfooエラー",
      "objectName": "fooError",
      "code": null
    },
    {
      "codes": null,
      "arguments": null,
      "defaultMessage": "人為的に発生させたbarエラー",
      "objectName": "barError",
      "code": null
    }
  ],
  "path": "/json"
}

HTML

<html><body>
<h1>Whitelabel Error Page</h1>
<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>
<div id='created'>Sun Jul 19 15:11:48 JST 2020</div>
<div>There was an unexpected error (type=Bad Request, status=400).</div>
<div>Validation failed for object=&#39;fooBarData&#39;. Error count: 2</div>
<div style='white-space:pre-wrap;'>
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
Error in object &#39;fooError&#39;: codes []; arguments []; default message [人為的に発生させたfooエラー]
Error in object &#39;barError&#39;: codes []; arguments []; default message [人為的に発生させたbarエラー]
    at example.FooBarController.page(FooBarController.java:20)
(中略)
    at java.base/java.lang.Thread.run(Thread.java:832)
</div>
</body></html>

Spring Boot 2.3 のソースコードでエラー情報を構築している箇所

DefaultErrorAttributes クラスで JSON や HTML で出力するエラー情報を構築している。

spring-boot/DefaultErrorAttributes.java at v2.3.0.RELEASE · spring-projects/spring-boot · GitHub

public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
  Map<String, Object> errorAttributes = new LinkedHashMap<>();
  errorAttributes.put("timestamp", new Date());
  addStatus(errorAttributes, webRequest);
  addErrorDetails(errorAttributes, webRequest, includeStackTrace);
  addPath(errorAttributes, webRequest);
  return errorAttributes;
}

ErrorMvcAutoConfiguration クラスでエラーページの HTML を構築している。

spring-boot/ErrorMvcAutoConfiguration.java at v2.3.0.RELEASE · spring-projects/spring-boot · GitHub

StringBuilder builder = new StringBuilder();
Date timestamp = (Date) model.get("timestamp");
Object message = model.get("message");
Object trace = model.get("trace");
if (response.getContentType() == null) {
  response.setContentType(getContentType());
}
builder.append("<html><body><h1>Whitelabel Error Page</h1>").append(
    "<p>This application has no explicit mapping for /error, so you are seeing this as a fallback.</p>")
    .append("<div id='created'>").append(timestamp).append("</div>")
    .append("<div>There was an unexpected error (type=").append(htmlEscape(model.get("error")))
    .append(", status=").append(htmlEscape(model.get("status"))).append(").</div>");
if (message != null) {
  builder.append("<div>").append(htmlEscape(message)).append("</div>");
}
if (trace != null) {
  builder.append("<div style='white-space:pre-wrap;'>").append(htmlEscape(trace)).append("</div>");
}
builder.append("</body></html>");

参考資料

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8