0

I am sending a DTO from client with a failed validation for one field. I tried to handle it in the Controller Advice, but it turns out it is not the instance of the ValidationException.class as that handler does not work. I checked it using the @ExceptionHandler(Exception.class) and it worked as expected, but I want to specify the Exception type properly.

This is the DTO:

public class BookDto {
    
    @NotBlank(message = "Name of the book cannot be empty!")
    @Size(min = 4, max = 30, message = "Name of the book must be between 4 and 30 characters 
    long!")
    public String name;

    @NotBlank(message = "Author of the book cannot be empty!")
    @Size(min = 4, max = 35, message = "Author of the book must be between 5 and 35 
    characters long!")
    public String author;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    public LocalDate publicationYear;

    @NotNull(message = "Pages of the book cannot be null!")
    @Digits(integer = 4, fraction = 0)
    public int pagesNumber;

    @NotBlank(message = "Publisher of the book cannot be empty!")
    @Size(min = 4, max = 30, message = "Publisher of the book must be between 4 and 30 
    characters long!")
    public String publisher;

}

This is the ControllerAdvice:

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(ResourceNotFoundException.class)
    protected ResponseEntity<?> resourceNotFoundException(ResourceNotFoundException ex, 
    WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), 
    request.getDescription(false));
        return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(ResourceWasDeletedException.class)
    protected ResponseEntity<MyGlobalExceptionHandler> handleDeleteException() {
        return new ResponseEntity<>(new MyGlobalExceptionHandler("This book was deleted!"), 
    HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(ValidationException.class)
    public ResponseEntity<?> handleValidationException(ValidationException exception, 
    WebRequest webRequest) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), exception.getMessage(), 
    webRequest.getDescription(false));
        return new ResponseEntity<>(errorDetails, HttpStatus.BAD_REQUEST);
    }

    /*    @ExceptionHandler(Exception.class)
    public ResponseEntity<?> globalExceptionHandler(Exception ex, WebRequest request) {
        ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), 
    request.getDescription(false));
        return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
    }*/

    @Data
    @AllArgsConstructor
    private static class MyGlobalExceptionHandler {
        private String message;
    }
}

This is the post method:

@PostMapping("/books")
@ResponseStatus(HttpStatus.CREATED)
public BookDto createBook(@Valid @RequestBody BookDto requestForSave){
    var book = converter.getMapperFacade().map(requestForSave, Book.class);
    log.debug("Book={}", book);
    var bookDto = converter.toDto((Book) bookService.create(book));
    log.debug("Book={}", bookDto);
    return bookDto;
}

When I commented the last Exception handler Postman receives a response with this:

enter image description here

So the ValidationException handler did not work. What type of the Exception is this?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • This is a default response raised by spring exception handler (for Rest APIs) when you do not explicitly override the behavior, It clearly tells that endpoint '/api/books' does not exist, as you defined mapping for /books only in your controller. – Manoj Sharma Jun 22 '22 at 12:18

1 Answers1

1

You can figure that out yourself: Restore your commented-out catch-all exception handler and just print or otherwise report ex.getClass(). exceptions are objects same as any other. They have a type, you can instanceof them, you can call .getClass() on them, you can pass them around like any other.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72