The default JSON error body of Spring Boot can be customized or extended by defining our own ErrorAttributes implementation. In Spring Boot we get an error response JSON format for free. Any thrown Exception is automatically translated to this JSON format and returned with a corresponding HTTP status.

Default implementation

As soon as we throw an Exception in a @RequestMapping annotated method of a @Controller, the thrown Exception is translated to a HTTP status and a JSON error body. The default JSON error body looks like:

{
  "timestamp": 1467191865498,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "java.lang.IllegalStateException",
  "message": "This is my exception message",
  "path": "/myendpoint"
}

Write your own ErrorAttributes implementation

What if we want extra attributes in this JSON error body? Just define an implementation for ErrorAttributes and register it as a Spring @Component. The following example will result in a customized JSON error response body with the cause of the exception included.

import org.springframework.boot.autoconfigure.web.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;

import java.util.HashMap;
import java.util.Map;

@Component
public class MyCustomErrorAttributes extends DefaultErrorAttributes {

    @Override
    public Map getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
        Map errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);

        Throwable throwable = getError(requestAttributes);
        Throwable cause = throwable.getCause();
        if (cause != null) {
            Map causeErrorAttributes = new HashMap<>();
            causeErrorAttributes.put("exception", cause.getClass().getName());
            causeErrorAttributes.put("message", cause.getMessage());
            errorAttributes.put("cause", causeErrorAttributes);
        }
        return errorAttributes;
    }
} 

Our resulting body will now look like:

{
  "timestamp": 1467191865498,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "java.lang.IllegalStateException",
  "message": "This is my exception message",
  "path": "/myendpoint",
  "cause": {
    "exception": "java.lang.IllegalArgumentException",
    "message": "This is the cause...."
  }
}

Happy developing!

shadow-left