1

I have written some logic and custom validation in Validator initialize method. But when exception occurs , custom exception was thrown but override by ValidationException

eg. HV000032: Unable to initialize ........

public class CustomValidator implements ConstraintValidator<CustomClass, CharSequence> {
@Override
public void initialize(CustomClass annota) {
   try {
      //code
   } catch (Exception e) {
      throw new CustomException("custom error ", e); <-- this exception is override by javax.validation.ValidationException...
   }
}

I want to get my custom exception and message . How can I implement that ...

Jack jdeoel
  • 4,554
  • 5
  • 26
  • 52

2 Answers2

0

In order to get your custom exception and message, you can catch the ValidationException thrown by the validation framework and extract your custom exception and message from it.

Something like this should work.

public class CustomValidator implements ConstraintValidator<CustomClass, CharSequence> {

    @Override
    public void initialize(CustomClass annota) {
        try {
            // code
        } catch (ValidationException e) {
            /* if an exception is thrown in the initialize method, the validation framework will not execute the isValid method. */
            throw new CustomException("validation error", e);
        } catch (Exception e) {
            throw new CustomException("custom error", e);
        }
    }

    @Override
    public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
        try {
            // validation logic
            return true;
        } catch (CustomException e) {
            // catch and rethrow your custom exception
            throw e;
        } catch (ValidationException e) {
            // catch and extract your custom exception and message
            Throwable cause = e.getCause();
            if (cause instanceof CustomException) {
                CustomException customException = (CustomException) cause;
                String message = customException.getMessage();
                // do something with customException and message
            }
            throw e;
        }
    }

}

the isValid method is the main method used by the validation framework to determine if an object is valid or not, and it is necessary to implement it in order to define the validation logic. Even if an exception is thrown in the initialize method, the isValid method is still necessary and will be executed for valid objects.

Nitesh Tosniwal
  • 1,796
  • 2
  • 12
  • 17
  • Hi . When exception occur in initialize , the operation stop there and isValid method is not executed.... – Jack jdeoel Feb 17 '23 at 07:21
  • Ok, my bad. You are correct, if an exception is thrown in the initialize method, the validation framework will not execute the isValid method. Instead, it will immediately throw a javax.validation.ValidationException with the error message "Unable to initialize constraint validator". This is why your CustomException is being overridden by the ValidationException. To work around this, you could try catching the ValidationException in the same try-catch block as your custom exception, and then wrapping the ValidationException in your custom exception. – Nitesh Tosniwal Feb 17 '23 at 07:44
0

That is expected behaviour for the validator. If you want to get other exception type then ValidationException, you can throw ConstraintDeclarationException out of your init method, which was somewhat designed to be used when the constraint declaration is wrong. Any other exceptions are wrapped into ValidationException, where a cause would be a thrown exception. So you could catch ValidationException in a place you are calling the validator and it's failing and then access your exception/message through getCause(). Something along next lines:

try {
    validator.validate( object );
}
catch (ValidationException e) {
    Throwable cause = e.getCause(); // <- your CustomException
}

Ideally, your initialize method should not throw any exceptions. The same is for the isValid - instead of throwing an exception, return false and a custom message explaining what failed:

@Override
public boolean isValid(CharSequence object, ConstraintValidatorContext constraintContext) {
    if ( object == null ) {
        return true;
    }

    boolean isValid = true;
    try {
        // some potentially failing logic:
    }
    catch (Exception e) {
        isValid = false;
        constraintContext.disableDefaultConstraintViolation();
        constraintContext.buildConstraintViolationWithTemplate(
                        e.getMessage()
                )
                .addConstraintViolation();
    }
    return isValid;
}
mark_o
  • 2,052
  • 1
  • 12
  • 18