Skip to content

WW-5819 Log a validator param that fails type conversion - #2062

Open
lukaszlenart wants to merge 2 commits into
mainfrom
feat/WW-5819-log-validator-param-conversion
Open

lukaszlenart wants to merge 2 commits into
mainfrom
feat/WW-5819-log-validator-param-conversion

Conversation

@lukaszlenart

Copy link
Copy Markdown
Member

Fixes WW-5819

Summary

A validator param that cannot be converted to its property type used to be left unset with no trace. For a range bound that silently switches the check off:

<field-validator type="localdate">
    <param name="min">01/02/2026</param>  <!-- not an ISO date: min stays null -->
</field-validator>

DefaultValidatorFactory.buildValidator now sets each param separately and logs a failed one with the validator class, param, value and cause — WARN by default, ERROR in devMode. Behaviour is unchanged: the validator is still built and the param stays unset. Failing the configuration instead is WW-5818 (8.0.0).

Design notes

  • Only params with a writable property are logged. The annotation builder adds a methodName routing param (read by DefaultActionValidatorManager) that no validator has a setter for; logging every failed set would have put a WARN on every annotated validator. Misspelled param names therefore stay silent, as before — that belongs with WW-5818.
  • The logged cause is OGNL's, not the converter's. XWorkConverter discards the TypeConversionException and returns NO_CONVERSION_POSSIBLE, so the cause seen here is e.g. NoSuchMethodException: ...setMin(java.lang.String). Surfacing the converter message would need a change in XWorkConverter, out of scope.
  • The log names the validator class, not the XML type alias — only the class name is known where the failure is caught.
  • Throwing mode (setProperty(..., true)) bypasses OgnlUtil's generic devMode WARN, so nothing is logged twice. The evaluation path (OGNL context, root, member access) is the same as setProperties.
  • LogCapture gained a messages(Level) overload; existing callers are unaffected.

The core suite surfaced one real case: SimpleAnnotationAction declares @DateRangeFieldValidator(min = "-1", max = "99"), whose bounds were always ignored. Left as is.

Test plan

  • DefaultValidatorFactoryTest: WARN by default, ERROR in devMode, valid value not logged, param without a property not logged
  • devMode level mutation caught by the test
  • mvn test -DskipAssembly -pl core — 3620 tests, 0 failures

🤖 Generated with Claude Code

…sion

A validator param that cannot be converted to its property type is still
left unset, but is now logged with the validator class, param, value and
cause: WARN by default, ERROR in devMode. Params without a writable
property (e.g. the annotation builder's methodName routing key) stay
silent, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lukaszlenart
lukaszlenart marked this pull request as ready for review October 26, 2026 11:56
@lukaszlenart
lukaszlenart requested a balanced review from Copilot October 26, 2026 11:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

5 open issues
What changed in this PR

This PR improves observability for Struts validator configuration by logging validator params that fail type conversion during validator construction (without changing existing runtime behavior).

Changes:

  • Set validator params individually and log failed type conversions at WARN (or ERROR in devMode)
  • Add test coverage validating log level behavior and non-logging cases
  • Extend LogCapture test utility to filter captured logs by Level
File Description
core/​src/​main/​java/​org/​apache/​struts2/​factory/​DefaultValidatorFactory.java Sets params one-by-one and logs conversion failures with devMode-dependent severity
core/​src/​test/​java/​org/​apache/​struts2/​factory/​DefaultValidatorFactoryTest.java Adds tests asserting new logging behavior and ensuring validator still builds
core/​src/​test/​java/​org/​apache/​struts2/​test/​LogCapture.java Captures log levels and adds messages(Level) filtering for assertions

Review effort: Lite

Comment thread core/src/test/java/org/apache/struts2/test/LogCapture.java Outdated
Comment thread core/src/test/java/org/apache/struts2/test/LogCapture.java Outdated
Comment thread core/src/test/java/org/apache/struts2/test/LogCapture.java Outdated
Comment thread core/src/test/java/org/apache/struts2/test/LogCapture.java Outdated
…ture

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants