51

My Spring Boot application provides the following REST controller:

@RestController @RequestMapping("/api/verify") public class VerificationController { final VerificationService verificationService; Logger logger = LoggerFactory.getLogger(VerificationController.class); public VerificationController(VerificationService verificationService) { this.verificationService = verificationService; } @GetMapping public void verify( @RequestParam(value = "s1") String s1, @RequestParam(value = "s2") String s2) { try { verificationService.validateFormat(s1, s2); } catch (InvalidFormatException e) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage()); } } } 

In case validateFormat() throws the InvalidFormatException the client gets a HTTP 400 which is correct. The default JSON response body however looks like this:

{ "timestamp": "2020-06-18T21:31:34.911+00:00", "status": 400, "error": "Bad Request", "message": "", "path": "/api/verify" } 

The message value is always empty even if I hard-code it like this:

throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "some string"); 

This is the exception class:

public class InvalidFormatException extends RuntimeException { public InvalidFormatException(String s1, String s2) { super(String.format("Invalid format: [s1: %s, s2: %s]", s1, s2)); } } 
7
  • 1
    are you sure there is no custom interceptor? Spring ExceptionHandler does not convert the timestamp to a date format (it will be in millis). as we see in your response Commented Jun 18, 2020 at 22:24
  • @KumarV None that I'd be aware of. I used the Spring Intializr with IntelliJ which did most of the setup. How could I find this out? Commented Jun 18, 2020 at 22:54
  • which version of spring boot you are using? Commented Jun 19, 2020 at 2:39
  • Downgrade your version to 2.1.x and give it a try just to make sure if it is something to do with latest boot version Commented Jun 19, 2020 at 3:23
  • Other reason I could think is that the BAD_REQUEST status could be thrown by Spring for some other reason and not from your exception handling block. Debug with break point in your controller to make sure it's actually executing your validateFormat() method or throw ResponseStatusException with some other status code Commented Jun 19, 2020 at 3:59

2 Answers 2

97

This behavior has changed with Spring Boot 2.3 and is intentional. See release notes for details.

Setting server.error.include-message=always in the application.properties resolves this issue.

Sign up to request clarification or add additional context in comments.

Comments

7

Setting server.error.include-message=always disclosures messages of internal exceptions and this might be a problem in production environment.

An alternative approach is to use ExceptionHandler. Here you can control what is transferred to client:

@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResponseStatusException.class) public ResponseEntity<String> handleBadRequestException(ResponseStatusException ex) { // if you want you can do some extra processing with message and status of an exception // or you can return it without any processing like this: return new ResponseEntity<>(ex.getMessage(), ex.getStatus()); } } 

1 Comment

It's often not good to expose exception messages in production. I'm surprised more people aren't taking that into consideration.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.