java – Spring ResponseStatusException does not return reason

java – Spring ResponseStatusException does not return reason

This answer was provided by user Hassan in the comments on the original question. Im only posting it as an answer to give it better visibility.

Basically, all you need to do is add server.error.include-message=always to your application.properties file, and now your message field should be populated.

This behavior was changed in Spring Boot 2.3 which you can read about here: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#changes-to-the-default-error-pages-content

I have the very same issue. If I use this construct

throw new ResponseStatusException(HttpStatus.NOT_FOUND, Error in update);

My message is not passed to client via JSON. For me, the only way to go around it was to create GlobalExceptionHandler class

package mypackage;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.Date;

@ControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(NotFoundException.class)
  public ResponseEntity<ErrorDTO> generateNotFoundException(NotFoundException ex) {
    ErrorDTO errorDTO = new ErrorDTO();
    errorDTO.setMessage(ex.getMessage());
    errorDTO.setStatus(String.valueOf(ex.getStatus().value()));
    errorDTO.setTime(new Date().toString());

    return new ResponseEntity<ErrorDTO>(errorDTO, ex.getStatus());
  }
}

I have also created my own Exception type

package mypackage;

import org.springframework.http.HttpStatus;

public class NotFoundException extends RuntimeException {

  public NotFoundException(String message) {
    super(message);
  }

  public HttpStatus getStatus() {
    return HttpStatus.NOT_FOUND;
  }
}

With this, I am able to throw exception from the controller and I am getting proper result in JSON – the message I want to see.

@PutMapping(/data/{id})
public DataEntity updateData(@RequestBody DataEntity data, @PathVariable int id) {
  throw new NotFoundException(Element not found);
}

I had to introduce ErrorDTO as well

package mypackage;

public class ErrorDTO {
  public String status;
  public String message;
  public String time;

  ...
  ...
  // getters and setters are here 
  ...
  ...
}

Update

As mentioned by @Hassan and @cunhaf (in comments under original question), the solution with

server.error.include-message=always

works perfectly fine with ResponseStatusException. Still, solution with GlobalExceptionHandler might be better in case someone wants to pass more info via Exception.

Source code

Samples can be found here: Global Exception Handler

java – Spring ResponseStatusException does not return reason

Strangely, Spring Boot 2.6.x changed this behavior again and the error message set on ResponseStatusException is not returned. I had to downgrade to 2.5.6 in order to solve it. In the end I had something like this:

 @DeleteMapping(/{id})
@ResponseStatus(HttpStatus.OK)  
public MessageResponse deleteById(@PathVariable(value = id) Integer id) {
    try {
        userService.deleteById(id); 
        
    } catch (Exception e) {
        throw new ResponseStatusException(HttpStatus.EXPECTATION_FAILED, Error deleting user. User has dependencies, e);
    }
}

Leave a Reply

Your email address will not be published.