Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception message not included in response when throwing ResponseStatusException in Spring Boot

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));     } } 
like image 335
Robert Strauch Avatar asked Jun 18 '20 21:06

Robert Strauch


People also ask

How do you throw a custom exception in spring boot?

Define a class that extends the RuntimeException class. You can define the @ExceptionHandler method to handle the exceptions as shown. This method should be used for writing the Controller Advice class file. Now, use the code given below to throw the exception from the API.

How do you throw an exception using ResponseEntity?

You have to provide implementation to use your error handler, map the response to response entity and throw the exception. Create new error exception class with ResponseEntity field. Custom error handler which maps the error response back to ResponseEntity.

How do you handle exceptions in spring boot rest?

Altogether, the most common way is to use @ExceptionHandler on methods of @ControllerAdvice classes so that the exception handling will be applied globally or to a subset of controllers. ControllerAdvice is an annotation introduced in Spring 3.2, and as the name suggests, is “Advice” for multiple controllers.


2 Answers

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.

like image 57
Robert Strauch Avatar answered Sep 20 '22 16:09

Robert Strauch


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());     } } 
like image 36
michal.jakubeczy Avatar answered Sep 18 '22 16:09

michal.jakubeczy