Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring REST using Jackson - 400 bad request logging

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!

like image 441
Eurig Jones Avatar asked Jun 26 '13 17:06

Eurig Jones


People also ask

How do you log a spring rest request response?

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.

How do you handle an exception in spring boot using annotations?

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.

How do I send a custom error message in REST API spring boot?

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.


4 Answers

@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void handle(HttpMessageNotReadableException e) {
    logger.warn("Returning HTTP 400 Bad Request", e);
}
like image 169
Jukka Avatar answered Oct 15 '22 23:10

Jukka


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;
    }
}
like image 37
David Welch Avatar answered Oct 15 '22 21:10

David Welch


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'
like image 43
Mike Avatar answered Oct 15 '22 23:10

Mike


You can set the log level to debug for this property in application.properties.

logging.level.org.springframework.web= DEBUG
like image 5
Naveen Muthusamy Avatar answered Oct 15 '22 22:10

Naveen Muthusamy