How to Throw a Custom Exception When Bean Validation In Spring Boot with Hibernate Validator Fails?
Asked Answered
Z

1

6

I'm using Spring Boot 2.0.1 with inclusion of validation-starter (which comes with Hibernate Validation 6.x) and trying to validate a method parameter and return objects in my Spring repository layer. There are basically a ParamObj and ReturnObj for this method,

@Repository
@Validated // Spring integration of validation
public class MyRepoImpl implements MyRepo {

  @Override
  @Valid
  public ReturnObj myMethod(@Valid ParamObj param) throw CustomException {
    try {
       // makes a call that might throw an exception
    } catch (Exception e) {
      throw new CustomException(/*...*/, e);
    }

    return returnObj;
  }
}

ParamObj and ReturnObj both use a simple set of Bean Validation annotations on some of their properties, e.g @Pattern, @Min, etc.. My problem is that with these annotations, if either ParamObj or ReturnObj fails the validation process, MyRepoImpl#myMethod() would throw javax.validation.ConstraintViolationException.

However, as you can see, the contract for myMethod() mandates to throw a CustomException. Yes, ConstraintViolationException is a RuntimeException, however, now the caller of MyRepoImpl#myMethod(), e.g. a service layer logic, needs to catch this RuntimeException in addition to CustomException.

And the reason is, I need to prevent all the exceptions from bubbling out of the service layer (for this particular Spring @Service I have which calls this repository) -- this service is part of a long list of services that are called via a service orchestration which constructs a larger encompassing object. In other word, this piece (result coming obtained via MyRepoImpl) is considered optional, and subsequently, its failure should only be logged but do not stop the whole process.

For that reason, I can't utilize ControllerAdvice to capture ConstraintViolationException for the entire application.

My goal is to be able, when the validation fails for either method parameter or return, to throw only CustomException back to the caller.

Is this possible with annotations only? I looked into MethodValidationPostProcessor but can't figure out if I can implement my own to accomplish this goal.

P.S. The only way I can think to achieve this is to forgo @Valid/@Validated and call Validator#validate(obj, ...) programmatically for the parameter and return value inside the try-catch block, catch the constraint exception, and throw my CustomException(). However, I want to know if I can avoid that and leave this hard coded validation out of the repository.

Zeke answered 30/6, 2019 at 1:13 Comment(0)
P
0

Since I was not here a year ago I would not have answered but since this is a common question as I can see through my experience with fellow students, I think the answer might be @ControllerAdvice, comes handy with any type of exceptions doc --> https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html

Psychotherapy answered 9/6, 2020 at 16:0 Comment(3)
A ControllerAdvice class only captures ConstraintViolationException. The question is, how one can throw a custom exception instead of define one for these validation errors?Zeke
ControllerAdvice catches any type of exception that extends Runtime.Psychotherapy
Yes, and that's not what the question here. Please reread the entire content.Zeke

© 2022 - 2024 — McMap. All rights reserved.