Spring Boot 2.3 で DefaultErrorAttributes と ErrorAttributeOptions を使ってエラー情報を取得する

## 概要

- Spring Boot 2.3 から DefaultErrorAttributes クラスの一部のコンストラクタとメソッドが非推奨 (Deprecated) になった (使えないわけではない)
- Spring Boot 2.3 から導入された ErrorAttributeOptions クラスを使用することで DefaultErrorAttributes からエラー情報を取得できる
 
## DefaultErrorAttributes で取得可能なエラー情報

[DefaultErrorAttributes \(Spring Boot 2\.3\.0\.RELEASE API\)](https://docs.spring.io/spring-boot/docs/2.3.0.RELEASE/api/org/springframework/boot/web/servlet/error/DefaultErrorAttributes.html) 等に取得可能なエラー情報の属性が記載されている。

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

## Spring Boot 2.2 用のサンプルコード

```java
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

public class ErrorAttributesGetter22 {

  /**
   * エラー情報を抽出する。
   *
   * @param req リクエスト情報
   * @return エラー情報
   */
  public static Map<String, Object> getErrorAttributes(HttpServletRequest req) {
    // DefaultErrorAttributes クラスで詳細なエラー情報を取得する
    ServletWebRequest swr = new ServletWebRequest(req);
    DefaultErrorAttributes dea = new DefaultErrorAttributes(true);
    return dea.getErrorAttributes(swr, true);
  }
}
```

## Spring Boot 2.3 用のサンプルコード

ErrorAttributeOptions クラスを使うことでいくつかの属性については取得するかどうか (エラー情報として残すかどうか) を選択できるようになった。

```java
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

public class ErrorAttributesGetter23 {

  /**
   * エラー情報を抽出する。
   *
   * @param req リクエスト情報
   * @return エラー情報
   */
  public static Map<String, Object> getErrorAttributes(HttpServletRequest req) {
    // DefaultErrorAttributes クラスで詳細なエラー情報を取得する
    ServletWebRequest swr = new ServletWebRequest(req);
    DefaultErrorAttributes dea = new DefaultErrorAttributes();
    ErrorAttributeOptions eao = ErrorAttributeOptions.of(
      ErrorAttributeOptions.Include.BINDING_ERRORS,
      ErrorAttributeOptions.Include.EXCEPTION,
      ErrorAttributeOptions.Include.MESSAGE,
      ErrorAttributeOptions.Include.STACK_TRACE);
    return dea.getErrorAttributes(swr, eao);
  }
}
```

## Spring Boot 2.3 の DefaultErrorAttributes クラスのソースコードを確認

取得対象としていない項目についてエラー情報から削除されている箇所のソースコード。

[spring\-boot/DefaultErrorAttributes\.java at v2\.3\.1\.RELEASE · spring\-projects/spring\-boot · GitHub](https://github.com/spring-projects/spring-boot/blob/v2.3.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java#L86-L105)

```java
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
	Map<String, Object> errorAttributes = getErrorAttributes(request, options.isIncluded(Include.STACK_TRACE));
	if (this.includeException != null) {
		options = options.including(Include.EXCEPTION);
	}
	if (!options.isIncluded(Include.EXCEPTION)) {
		errorAttributes.remove("exception");
	}
	if (!options.isIncluded(Include.STACK_TRACE)) {
		errorAttributes.remove("trace");
	}
	if (!options.isIncluded(Include.MESSAGE) && errorAttributes.get("message") != null) {
		errorAttributes.put("message", "");
	}
	if (!options.isIncluded(Include.BINDING_ERRORS)) {
		errorAttributes.remove("errors");
	}
	return errorAttributes;
}
```

## 参考資料

- [DefaultErrorAttributes \(Spring Boot 2\.3\.1\.RELEASE API\)](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/api/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.html)
- [ErrorAttributeOptions \(Spring Boot 2\.3\.1\.RELEASE API\)](https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/api/org/springframework/boot/web/error/ErrorAttributeOptions.html)
- [spring\-boot/DefaultErrorAttributes\.java at v2\.3\.1\.RELEASE · spring\-projects/spring\-boot · GitHub](https://github.com/spring-projects/spring-boot/blob/v2.3.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/reactive/error/DefaultErrorAttributes.java)
- [spring\-boot/ErrorAttributeOptions\.java at v2\.3\.1\.RELEASE · spring\-projects/spring\-boot · GitHub](https://github.com/spring-projects/spring-boot/blob/v2.3.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/error/ErrorAttributeOptions.java)
- [spring\-boot/BasicErrorController\.java at v2\.3\.1\.RELEASE · spring\-projects/spring\-boot · GitHub](https://github.com/spring-projects/spring-boot/blob/v2.3.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/BasicErrorController.java)