thymeleaf / thymeleaf-spring

Thymeleaf integration module for Spring
http://www.thymeleaf.org
Apache License 2.0
434 stars 156 forks source link

Cannot call #fields.detailedErrors() from a Spring Webflow form #175

Open jchafik opened 6 years ago

jchafik commented 6 years ago

Thymeleaf 3.0.9.RELEASE Thymeleaf Security 3.0.2.RELEASE Thymeleaf Layout 2.2.2

Spring 4.3.13.RELEASE Spring Webflow 2.4.5.RELEASE

Calling #fields.detailedErrors() from a Spring Webflow form results in a BindingModel$FieldPrefixErrorMessage exception.

The issue is that Webflow has its own getFieldErrors method that does not accept a wildcard without the field prefix (org.springframework.webflow.mvc.view.BindingModel.getFieldErrors(String)). I believe it expects beanName.expression instead of expression, or for you to explicitly call getAllErrors if attempting to get all errors (as is done in the constructor for org.springframework.web.servlet.support.BindStatus):

if ("*".equals(this.expression)) {
    this.objectErrors = this.errors.getAllErrors();
}
else if (this.expression.endsWith("*")) {
    this.objectErrors = this.errors.getFieldErrors(this.expression);
}
else {
    this.objectErrors = this.errors.getFieldErrors(this.expression);
    ...
}

Relevant stack trace:

Caused by: java.lang.IllegalArgumentException: The fieldPrefix is required
    at org.springframework.util.Assert.hasText(Assert.java:181)
    at org.springframework.webflow.mvc.view.BindingModel$FieldPrefixErrorMessage.<init>(BindingModel.java:353)
    at org.springframework.webflow.mvc.view.BindingModel.getFieldErrors(BindingModel.java:123)
    at org.thymeleaf.spring4.util.FieldUtils.computeDetailedErrors(FieldUtils.java:166)
    at org.thymeleaf.spring4.util.FieldUtils.detailedErrors(FieldUtils.java:114)
    at org.thymeleaf.spring4.expression.Fields.detailedErrors(Fields.java:94)

I believed this was introduced by the fix to #90

https://github.com/thymeleaf/thymeleaf-spring/commit/a417f24814a3933a93cb34161704026d09a55118#diff-7ed912361ca43f85acc57b043a7f8dd1R166

danielfernandez commented 6 years ago

Could you please confirm that you are calling #fields.detailedErrors() from inside an element with a th:object for the form-backing bean? (such as <form th:object="${beanName}">)

The thing is that the Errors object that is asked for its #getFieldErrors() is obtained from the BindStatus and this BindStatus is already obtained by (internally) specifying the beanName. So it should already contain that information.

So I'm wondering if maybe you are placing your call to #fields.detailedErrors() outside the scope of the form, and therefore there is no way for the bean name to be determined and used underneath...

jchafik commented 6 years ago

Confirmed. The error actually presented itself when updating the library, and went away again when I downgraded. Again, the issue is specific to spring webflow.