How to customise javax.validation.Valid error response

320 Views Asked by At

I have this controller:

@RequestMapping(
    method = RequestMethod.GET,
    value = Endpoints.TRUE_MATCH,
    produces = {"application/json"})
public ResponseEntity<ResponseWrapper<List<TrueMatch>>> getTrueMatch(
    @Valid Details details) {
    ...
}

Details contains @NotNull private TransmissionType transmissionType; where is an enum. If a request has a transmissionType parameter which doesn't match any enum, the response looks something like this:

{
    "status": 400,
    "validationErrors": {
        "transmissionType": "Failed to convert property value of type 'java.lang.String' to required type 'my.application.model.TransmissionType' for property 'transmissionType'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@javax.validation.constraints.NotNull ie.aviva.services.motor.cartellservice.model.TransmissionType] for value 'foo'; nested exception is java.lang.IllegalArgumentException: No enum constant ie.aviva.services.motor.cartellservice.model.TransmissionType.automatic'"
    },
    "title": "Bad Request"
}

Is it possible to override the message in transmissionType so the response looks something like this?

{
    "status": 400,
    "validationErrors": {
        "transmissionType": "Some custom message"
    },
    "title": "Bad Request"
}
1

There are 1 best solutions below

0
Honza Zidek On

You can implement a handler for MethodArgumentNotValidException:

Exception to be thrown when validation on an argument annotated with @Valid fails.

@RestControllerAdvice
public class MyErrorHandler {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<MyErrorResponse> handle(MethodArgumentNotValidException ex) {
        // Fetch whatever data you need from the original exception ex
        // e.g. ex.getAllErrors().getXXXX()
        return ResponseEntity
                .status(HttpStatus.BAD_REQUEST)
                .body(MyErrorResponse.builder()
                        //.whicheverFieldsYouNeed(xxxx)
                        .build());
    }