I have spring REST set up fine using Jackson/JSON and everything works.
But I knowingly introduced an error in the structure of the message which resulted in a 400 - Bad Request. But there was no log output on the server. The error I would be expecting would be something like "Jackson unknown property exception" or whatever but it was caught and a 400 error was sent to the client, but no log of the exception on the server.
I don't want to debug everything on the server clearly, but I want Spring network level exceptions like this clearly labelled as error.
What is the correct way to switch this on?
Thanks!
Custom Request Logging Among the Spring request interceptors, one of the noteworthy interfaces is HandlerInterceptor, which we can use to log the incoming request by implementing the following methods: preHandle() – we execute this method before the actual controller service method.
The @ExceptionHandler is an annotation used to handle the specific exceptions and sending the custom responses to the client. Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown.
The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation's reason field. Although we can only return a generic error message, we can specify exception-specific error messages.
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void handle(HttpMessageNotReadableException e) {
logger.warn("Returning HTTP 400 Bad Request", e);
}
Building on @Jukka's answer, you can enable this globally for all controllers using @ControllerAdvice
(introduced in Spring 3.2). It does require a little code on your end, but in my experience you usually end up needing a global error handling configuration anyways and this allows you to set breakpoints / easily inspect the problems.
An example of this is below:
@ControllerAdvice
public class ControllerConfig {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void handle(HttpMessageNotReadableException e) {
log.warn("Returning HTTP 400 Bad Request", e);
throw e;
}
}
In case anyone else stumbles on this issue, the following worked for me in Spring Boot 2 / Spring 5 and didn't require a code change.
I set the log level for org.springframework.web.servlet.mvc.method.annotation
to DEBUG
. In my case I was seeing 400 responses in my client code but no logging on the server side (even with a custom error handler). After changing that log level the problem was obvious:
DEBUG 172.19.0.16 cs 2018-Jun-08 20:55:08.415 [https-jsse-nio-443-exec-9] - method.annotation.RequestResponseBodyMethodProcessor[line ?] - Read [class java.lang.String] as "application/xml;charset=UTF-8" with [org.springframework.http.converter.xml.MarshallingHttpMessageConverter@2de50ee4]
DEBUG 172.19.0.16 cs 2018-Jun-08 20:55:08.418 [https-jsse-nio-443-exec-9] - method.annotation.ServletInvocableHandlerMethod[line ?] - Failed to resolve argument 0 of type 'java.lang.String'
org.springframework.beans.TypeMismatchException: Failed to convert value of type 'core.dto.RequestDTO' to required type 'java.lang.String'
You can set the log
level to debug for this property in application.properties
.
logging.level.org.springframework.web= DEBUG
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With