0

I would like to have a customized message for the HTTP response i.e.

{
    "timestamp": "2020-06-30T00:40:58.558+00:00",
    "status": 417,
    "error": "Expectation Failed",
    "message": "",
    "path": "/test/v1/tests/4ae767e1-ae83-66dd-9180-81160f766d90"
}

Instead of the above message, I want a customized "message":

{
    "timestamp": "2020-06-30T00:40:58.558+00:00",
    "status": 417,
    "error": "Expectation Failed",
    "message": "#/test: 8.0 is not higher or equal to 100",
    "path": "/test/v1/tests/4ae767e1-ae83-66dd-9180-81160f766d90"
}

Here is my exception class:

@ResponseStatus(value = HttpStatus.EXPECTATION_FAILED)
public class ThrowError extends Exception {

    private static final long serialVersionUID = 1L;
    
    public ThrowErrorMessage(String message){

        super(message);
    }

Here is the catch block of a function in the controller:

catch(Exception e) 
        {   
  //basically I want e.getMessage() to be the value of the "Message" key
            throw new ThrowErrorMessage(e.getMessage()); 
            
        }
        

3 Answers 3

5

If you are using Spring boot 2.3, then setting the below property in application.properties will add your custom message in the response.

server.error.include-message=always
Sign up to request clarification or add additional context in comments.

Comments

2

In your controller, do not do a try-catch. Instead, directly do a throws on the method, like so:

@RestController
@RequestMapping(value = "/api", 
    consumes = { MediaType.APPLICATION_JSON_VALUE }, 
    produces = { MediaType.APPLICATION_JSON_VALUE })
public class YourClassController {
    @GetMapping(value = "/{id}")
    public ResponseEntity<ResponseDto> getSomething(
            @PathVariable("id") String id
    ) throws ThrowError {
        
        //your code, for example:
        HttpStatus httpStatus = HttpStatus.OK;
        ResponseDto responseDto = new ResponseDto;
        responseDto.timestamp(LocalDateTime.now())
            .status(status);

        //maybe some more code

        return new ResponseEntity<>(responseDto, httpStatus);
    }
}

@JsonPropertyOrder({"timestamp", "status", ...})
public class ResponseDto implements Serializable {

    private static final long serialVersionUID = -7377277424125144224L;
    
    //The fields that you want to return if there is no error, example
    @JsonProperty("timestamp")
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private LocalDateTime timeStamp;

    private Integer status;
    
    //more fields

    //getter, setters and so on.
}

And if there is an error, you will get what you wish, i.e

{
    "timestamp": "2020-06-30T00:40:58.558+00:00",
    "status": 417,
    "error": "Expectation Failed",
    "message": "#/test: 8.0 is not higher or equal to 100",
    "path": "/test/v1/tests/4ae767e1-ae83-66dd-9180-81160f766d90"
}

If you want to further customize the error response, you can do this:

@Component
public class CustomErrorAttributes extends DefaultErrorAttributes {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
     
        Map<String, Object> map = super.getErrorAttributes(webRequest, options);

        //customize the values of the map here i.e timestamp, status, error, message, path

        return map;
    }
}

3 Comments

catCoder69 does that answer your questions?
@jumping_monkey I like the idea, but the function that I have defined has some other return type (my return type is of a class type, the class being defined by me)...so my aim is, if everything goes good, then I return an object of that class type, otherwise we get the error message in the stated format.
I get what you mean, my answer caters for that, look at the return return new ResponseEntity<>(responseDto, httpStatus);. It is returning a response body, i.e responseDto, in your case, that would be your class object. I have updated my answer with an example.
0

Customize error response, based on Exception can be done, using ExceptionHandler. You can also reuse DefaultErrorAttributes and ResponseEntityExceptionHandler like this: https://stackoverflow.com/a/64866190/548473

See also Using ErrorAttributes in our custom ErrorController

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.