diff --git a/src/main/java/org/apache/commons/validator/Field.java b/src/main/java/org/apache/commons/validator/Field.java index 86f86c54a..ac417b728 100644 --- a/src/main/java/org/apache/commons/validator/Field.java +++ b/src/main/java/org/apache/commons/validator/Field.java @@ -434,7 +434,7 @@ Object[] getIndexedProperty(final Object bean) throws ValidatorException { indexProp = PropertyUtils.getProperty(bean, getIndexedListProperty()); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new ValidatorException(e.getMessage()); + throw new ValidatorException(e); } if (indexProp instanceof Collection) { @@ -463,7 +463,7 @@ private int getIndexedPropertySize(final Object bean) throws ValidatorException indexProp = PropertyUtils.getProperty(bean, getIndexedListProperty()); } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new ValidatorException(e.getMessage()); + throw new ValidatorException(e); } if (indexProp == null) { @@ -611,8 +611,7 @@ public String getVarValue(final String mainKey) { * @throws ValidatorException */ private void handleMissingAction(final String name) throws ValidatorException { - throw new ValidatorException("No ValidatorAction named " + name - + " found for field " + getProperty()); + throw new ValidatorException("No ValidatorAction named " + name + " found for field " + getProperty()); } /** diff --git a/src/main/java/org/apache/commons/validator/ValidatorAction.java b/src/main/java/org/apache/commons/validator/ValidatorAction.java index cbb7ae9bc..54ec68865 100644 --- a/src/main/java/org/apache/commons/validator/ValidatorAction.java +++ b/src/main/java/org/apache/commons/validator/ValidatorAction.java @@ -153,9 +153,7 @@ boolean executeValidationMethod(final Field field, // TODO What is this the correct value type? // both ValidatorAction and Validator are added as parameters final Map params, final ValidatorResults results, final int pos) throws ValidatorException { - params.put(Validator.VALIDATOR_ACTION_PARAM, this); - try { if (validationMethod == null) { synchronized (this) { @@ -165,52 +163,40 @@ boolean executeValidationMethod(final Field field, loadValidationMethod(); } } - final Object[] paramValues = getParameterValues(params); - if (field.isIndexed()) { handleIndexedField(field, pos, paramValues); } - Object result = null; try { result = validationMethod.invoke(getValidationClassInstance(), paramValues); - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new ValidatorException(e.getMessage()); + throw new ValidatorException(e); } catch (final InvocationTargetException e) { - if (e.getTargetException() instanceof Exception) { throw (Exception) e.getTargetException(); - } if (e.getTargetException() instanceof Error) { throw (Error) e.getTargetException(); } } - final boolean valid = isValid(result); if (!valid || valid && !onlyReturnErrors(params)) { results.add(field, name, valid, result); } - if (!valid) { return false; } - // TODO This catch block remains for backward compatibility. Remove // this for Validator 2.0 when exception scheme changes. } catch (final Exception e) { if (e instanceof ValidatorException) { throw (ValidatorException) e; } - getLog().error("Unhandled exception thrown during validation: " + e.getMessage(), e); - results.add(field, name, false); return false; } - return true; } @@ -368,17 +354,13 @@ private Object[] getParameterValues(final Map params) { private Object getValidationClassInstance() throws ValidatorException { if (Modifier.isStatic(validationMethod.getModifiers())) { instance = null; - } else if (instance == null) { try { instance = validationClass.getConstructor().newInstance(); } catch (final ReflectiveOperationException e) { - final String msg1 = "Couldn't create instance of " + className + ". " + e.getMessage(); - - throw new ValidatorException(msg1); + throw new ValidatorException("Couldn't create instance of " + className + ". " + e.getMessage()); } } - return instance; } @@ -503,7 +485,7 @@ private void loadParameterClasses(final ClassLoader loader) throws ValidatorExce parameterClasses[i] = loader.loadClass(paramClassName); } catch (final ClassNotFoundException e) { - throw new ValidatorException(e.getMessage()); + throw new ValidatorException(e); } } @@ -525,7 +507,7 @@ private void loadValidationClass(final ClassLoader loader) throws ValidatorExcep try { validationClass = loader.loadClass(className); } catch (final ClassNotFoundException e) { - throw new ValidatorException(e.toString()); + throw new ValidatorException(e); } } diff --git a/src/main/java/org/apache/commons/validator/ValidatorException.java b/src/main/java/org/apache/commons/validator/ValidatorException.java index 987dc9f8c..c12704413 100644 --- a/src/main/java/org/apache/commons/validator/ValidatorException.java +++ b/src/main/java/org/apache/commons/validator/ValidatorException.java @@ -14,12 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.apache.commons.validator; /** - * The base exception for the Validator Framework. All other - * {@code Exception}s thrown during calls to - * {@code Validator.validate()} are considered errors. + * The base exception for the Validator Framework. All other {@code Exception}s thrown during calls to {@code Validator.validate()} are considered errors. */ public class ValidatorException extends Exception { @@ -34,10 +33,22 @@ public ValidatorException() { /** * Constructs an Exception with the specified detail message. * - * @param message The error message. + * @param message The error message. */ public ValidatorException(final String message) { super(message); } + /** + * Constructs a new exception with the specified cause and a detail message of {@code (cause==null ? null : cause.toString())} (which typically contains the + * class and detail message of {@code cause}). This constructor is useful for exceptions that are little more than wrappers for other throwables (for + * example, {@link java.security.PrivilegedActionException}). + * + * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A {@code null} value is permitted, and indicates that the + * cause is nonexistent or unknown.) + * @since 1.11.0 + */ + public ValidatorException(final Throwable cause) { + super(cause); + } } \ No newline at end of file diff --git a/src/test/java/org/apache/commons/validator/ValidatorExceptionTest.java b/src/test/java/org/apache/commons/validator/ValidatorExceptionTest.java new file mode 100644 index 000000000..577a6944b --- /dev/null +++ b/src/test/java/org/apache/commons/validator/ValidatorExceptionTest.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.validator; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +/** + * Unit tests for {@link ValidatorException}. + */ +public class ValidatorExceptionTest { + + /** + * Tests the no-arg constructor. + */ + @Test + public void testConstructorNoArg() { + final ValidatorException e = new ValidatorException(); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + /** + * Tests the constructor with a cause. + */ + @Test + public void testConstructorWithCause() { + final Throwable cause = new RuntimeException("root cause"); + final ValidatorException e = new ValidatorException(cause); + assertSame(cause, e.getCause()); + } + + /** + * Tests the constructor with a message. + */ + @Test + public void testConstructorWithMessage() { + final String message = "test error message"; + final ValidatorException e = new ValidatorException(message); + assertEquals(message, e.getMessage()); + assertNull(e.getCause()); + } + + /** + * Tests the constructor with a null cause. + */ + @Test + public void testConstructorWithNullCause() { + final ValidatorException e = new ValidatorException((Throwable) null); + assertNull(e.getCause()); + assertNull(e.getMessage()); + } + + /** + * Tests the constructor with a null message. + */ + @Test + public void testConstructorWithNullMessage() { + final ValidatorException e = new ValidatorException((String) null); + assertNull(e.getMessage()); + assertNull(e.getCause()); + } + + /** + * Tests that ValidatorException is an instance of Exception. + */ + @Test + public void testIsException() { + final ValidatorException e = new ValidatorException(); + assertEquals(Exception.class, e.getClass().getSuperclass()); + } + + /** + * Tests that ValidatorException can be thrown and caught. + */ + @Test + public void testThrowAndCatch() { + final String message = "thrown exception"; + final ValidatorException e = assertThrows(ValidatorException.class, () -> { + throw new ValidatorException(message); + }); + assertEquals(message, e.getMessage()); + } +}