I've been working on a web service that I've been building in Spring Boot, however one issue I've come across is that when Spring Boot comes across a problem, the structure of the JSON response it generates doesn't match the structure of errors I'm generating in endpoints. The problem with this is that the clients of the service are required to interpret multiple error response structures, which really is unnecessary. The structure of a default error generated by Spring Boot might look something like this;

{
    "timestamp": 1507556642643,
    "status": 400,
    "error": "Bad Request",
    "exception": "org.springframework.web.method.annotation.MethodArgumentTypeMismatchException",
    "message": "Failed to convert value of type 'java.lang.String' to required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "lkjhg"",
    "path": "/users/lkjhg"
}

While the errors generated in my endpoints are returned in a completely different structure. It is possible for an endpoint to return multiple errors in the service I'm working on, so my error responses look something like this;

{
    "errors": [
        {
            "code": 123,
            "message": "Email address is required"
        },
        {
            "code": 123,
            "message": "Password is required"
        }
    ]
}

In an idea world I'd like the responses generated by Spring Boot to follow the structure I'm using about. It turns out this is pretty easy, you just need to create a configuration class that Spring Boot will use, and here's mine;

@Configuration
@EnableWebMvc
public class AppConfiguration extends WebMvcConfigurerAdapter {

    /**
     * Overrides the default JSON error structure
     * @return DefaultErrorAttributes
     */
    @Bean
    public ErrorAttributes errorAttributes() {
        return new DefaultErrorAttributes() {
            @Override
            public Map getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
                Map errorAttributes = super.getErrorAttributes(requestAttributes, includeStackTrace);

                /* Create map to hold the error */
                Map error = new HashMap<>();
                error.put("code", errorAttributes.get("status"));
                error.put("message", errorAttributes.get("error"));

                /* Create a list to hold the map */
                List> errors = new ArrayList<>();
                errors.add(error);

                /* Create the final response Map and add the errors */
                Map errorResponse = new HashMap<>();
                errorResponse.put("errors", errors);

                return errorResponse;
            }
        };
    }

}

The response generated by Spring Boot now, looks like this;

{
    "errors": [
        {
            "code": 400,
            "message": "Bad Request"
        }
    ]
}

Meaning now, that any consumers of my API will only have to deal with a single error response structure.

Comments

There are no comments, why not be the first?

Submit a reply

Your e-mail address will not be published, all fields are required.

SIGNUP TO THE NEWSLETTER

Get useful tips on web application development and software engineering.