Issue
I have a custom validation for amount property in request body and if failed validation its throw my BadRequestException (extend from my BaseException) and in ExceptionTranslator class (marked with @ControllerAdvice) i have two method for catch exceptions, one for BaseException and other one for RuntimeException my problem is when validation failed i expect handleBaseException invoked but handleRuntimeException invoked with message Unexpected exception during isValid call.
@Override
public boolean isValid(Long value, ConstraintValidatorContext context) {
if (value < appConfig.getMinAmount()) {
throw new BadRequestException()
.addErrorDetail(null, I18nKey.EXCEPTION.AMOUNT_SIZE, appConfig.getMinAmount());
}
return true;
}
public class BadRequestException extends BaseException {
public BadRequestException() {
super(HttpStatus.BAD_REQUEST);
}
}
@ControllerAdvice
public class ExceptionTranslator {
@ExceptionHandler(value = {BaseException.class})
public ResponseEntity<Object> handleBaseException(BaseException ex) {
//Some work
}
@ExceptionHandler(value = {RuntimeException.class})
protected ResponseEntity<Object> handleRuntimeException(RuntimeException ex) {
//Some work
}
}
Solution
There are many situations where you can apply a custom validation correctly:
When dealing with DTO validation, you must annotate the request body received in the request with @Validated
.
On the custom validator, the thrown exception will be MethodArgumentNotValidException
if some constraints violated (verifications on some fields) or an exception ConstraintViolationException
on your case, this is the exception that will be thrown not the BaseException.
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> onConstraintValidationException(
final MethodArgumentNotValidException exception, HttpServletRequest request) {...}
So, the BaseException will be within a ConstraintViolationException catched by the controller at the point :
@ExceptionHandler(value = {RuntimeException.class})
Answered By - AceneKASDI
Answer Checked By - Willingham (JavaFixing Volunteer)