ErroREST Spring Boot Starter
Complete, ready to use exception handling for Spring Boot REST services.
Features
- unified HTTP response format for every unhandled exception (thrown from controllers or servlet filters)
- unified exception log format
- JSON and XML HTTP response body types
- configurable HTTP response body format
- support for custom exceptions
- support for Bean Validation exceptions
- support for Spring Web 4xx errors
- RestTemplate that supports ErroREST HTTP responses
- support for Spring Security exceptions
Installing
repositories {
mavenCentral()
}
dependencies {
compile 'com.github.mkopylec:errorest-spring-boot-starter:2.0.0'
}
HTTP response format
The starter maps all unhandled exceptions to specific ErroREST HTTP responses.
JSON format
If the incoming HTTP request contains Accept: application/json
header, the HTTP response will contain Content-Type: application/json
header. The response body will be:
{
"id":"<random id>",
"errors":[
{
"code":"<some error code>",
"description":"<some error description>"
}
]
}
XML format
If the incoming HTTP request contains Accept: application/xml
header, the HTTP response will contain Content-Type: application/xml
header. The response body will be:
<body>
<id>random id</id>
<errors>
<error>
<code>some error code</code>
<description>some error description</description>
</error>
</errors>
</body>
Log format
All unhandled exceptions are logged using the following template:
ID: <random id> | <http request method> <http request uri> <http response status> | <some error code>: <some error description> | <another error code>: <another error description> | ...
Exceptions are always logged with stack trace.
Basic usage
To start using the starter in a REST service the service must be a Spring Boot web application:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
No extra configuration and no custom exception handler is needed to ensure that all thrown exceptions will be properly mapped to ErroREST HTTP responses.
Advanced usage
The starter supports the following features to make error handling as easy as possible.
HTTP response body type
By default response body includes error codes and descriptions. To hide error descriptions set an appropriate configuration property:
errorest.response-body-format: without_descriptions
Custom exceptions
Custom exceptions can be configured how they will be mapped to ErroREST HTTP responses by extending ApplicationException
, for example:
public class SampleApplicationException extends ApplicationException {
public SampleApplicationException(String message, Throwable cause) {
super(new ApplicationExceptionConfiguration()
.withResponseHttpStatus(BAD_REQUEST)
.withLoggingLevel(WARN)
.withCause(cause)
.addError("SAMPLE_ERROR_CODE", message)
);
}
}
The SampleApplicationException
from the example will be mapped to ErroREST HTTP response with 400 (bad request) status and body like so:
{
"id":"<random id>",
"errors":[
{
"code":"SAMPLE_ERROR_CODE",
"description":message
}
]
}
The exception will be logged as warning.
Bean Validation exceptions
The starter is able to map Bean Validation exceptions to ErroREST HTTP responses with 422 statuses (unprocessable entity). For this kind of exceptions a validation constraint message
is mapped to an error code and an error description becomes a description of the invalid value. For example, if the following validation fails:
public class SampleRequestBody {
@NotNull(message = "EMPTY_MESSAGE")
private String message;
@Max(message = "NUMBER_TOO_BIG", value = 10)
private int number;
...
}
the result will mapped to ErroREST HTTP response with body:
{
"id":"<random id>",
"errors":[
{
"code":"EMPTY_MESSAGE",
"description":"Invalid 'message' value: null"
},
{
"code":"NUMBER_TOO_BIG",
"description":"Invalid 'number' value: 11"
}
]
}
By default all validation errors are logged with WARN
level. To change the logging level set an appropriate configuration property:
errorest.bean-validation-error.logging-level: <logging level>
HTTP 4xx errors
Spring Web includes a set of generic exceptions that represents HTTP client errors, for example HttpMessageNotReadableException
or HttpRequestMethodNotSupportedException
. Those exceptions are automatically mapped to ErroREST HTTP responses with a proper HTTP statuses. By default 4xx HTTP errors are logged with WARN
level. To change the logging level set an appropriate configuration property:
errorest.http-client-error.logging-level: <logging level>
RestTemplate
The starter includes a special RestTemplate
called ErrorestTemplate
which fully supports ErroREST HTTP responses. The ErrorestTemplate
in case of HTTP error throws ExternalHttpRequestException
which extends HttpStatusCodeException
. The ExternalHttpRequestException
overrides the getMessage()
method to return much more detailed information about HTTP error than HttpStatusCodeException
. It also defines getResponseBodyAsErrors()
method which maps ErroREST HTTP response bodies to Errors
objects. The usage of ErrorestTemplate
is the same as of normal RestTemplate
:
RestOperations client = new ErrorestTemplate();
try {
client.getForObject("http://exmaple.com", String.class);
} catch (ExternalHttpRequestException ex) {
String detailedMessage = ex.getMessage();
Errors errors = ex.getResponseBodyAsErrors();
...
}
If the ExternalHttpRequestException
will not be handled manually it will be handled automatically by the starter. In that case a received ErroREST HTTP response will be proxied up to the client.
Spring Security exceptions
The starter supports mapping Spring Security exceptions to ErroREST HTTP responses if the following dependency is added:
dependencies {
compile 'org.springframework.boot:spring-boot-starter-security:2.0.1.RELEASE'
}
To support the HTTP Security configuration and method secured with annotations ErrorestAccessDeniedHandler
and ErrorestAuthenticationEntryPoint
are needed:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private ErrorestAuthenticationEntryPoint authenticationEntryPoint;
@Autowired
private ErrorestAccessDeniedHandler accessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler)
.and()
...
}
}
Configuration properties list
The following list contains all available configuration properties with their default values.
errorest:
response-body-format: full # HTTP response body format.
http-client-error:
logging-level: warn # HTTP 4xx errors logging level.
bean-validation-error:
logging-level: warn # Validation errors logging level.
License
ErroREST Spring Boot Starter is published under Apache License 2.0.