Browse Source

Retain root cause for parsing patterns in @DateTimeFormat

The support for fallback parsing patterns in @DateTimeFormat introduced
in gh-20292 introduced a regression in that the original cause of the
parsing exception was no longer retained.

gh-26777 addressed that regression for `java.time` support; whereas,
this commit addresses that regression for legacy Date types.

This commit ensures that the original ParseException is set as the
cause for any newly created ParseException, thereby retaining the
original exception as the root cause.

Closes gh-26804
pull/26822/head
Sam Brannen 4 years ago
parent
commit
0f31830ae2
  1. 4
      spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java
  2. 35
      spring-context/src/test/java/org/springframework/format/datetime/DateFormattingTests.java

4
spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java

@ -219,9 +219,11 @@ public class DateFormatter implements Formatter<Date> { @@ -219,9 +219,11 @@ public class DateFormatter implements Formatter<Date> {
}
}
if (this.source != null) {
throw new ParseException(
ParseException parseException = new ParseException(
String.format("Unable to parse date time value \"%s\" using configuration from %s", text, this.source),
ex.getErrorOffset());
parseException.initCause(ex);
throw parseException;
}
// else rethrow original exception
throw ex;

35
spring-context/src/test/java/org/springframework/format/datetime/DateFormattingTests.java

@ -119,6 +119,36 @@ public class DateFormattingTests { @@ -119,6 +119,36 @@ public class DateFormattingTests {
assertThat(binder.getBindingResult().getFieldValue("styleDate")).isEqualTo("10/31/09");
}
@Test
void styleDateWithInvalidFormat() {
String propertyName = "styleDate";
String propertyValue = "99/01/01";
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.add(propertyName, propertyValue);
binder.bind(propertyValues);
BindingResult bindingResult = binder.getBindingResult();
assertThat(bindingResult.getErrorCount()).isEqualTo(1);
FieldError fieldError = bindingResult.getFieldError(propertyName);
TypeMismatchException exception = fieldError.unwrap(TypeMismatchException.class);
exception.printStackTrace(System.err);
assertThat(exception)
.hasMessageContaining("for property 'styleDate'")
.hasCauseInstanceOf(ConversionFailedException.class).getCause()
.hasMessageContaining("for value '99/01/01'")
.hasCauseInstanceOf(IllegalArgumentException.class).getCause()
.hasMessageContaining("Parse attempt failed for value [99/01/01]")
.hasCauseInstanceOf(ParseException.class).getCause()
// Unable to parse date time value "99/01/01" using configuration from
// @org.springframework.format.annotation.DateTimeFormat(pattern=, style=S-, iso=NONE, fallbackPatterns=[])
.hasMessageContainingAll(
"Unable to parse date time value \"99/01/01\" using configuration from",
"@org.springframework.format.annotation.DateTimeFormat",
"style=S-", "iso=NONE", "fallbackPatterns=[]")
.hasCauseInstanceOf(ParseException.class).getCause()
.hasMessageStartingWith("Unparseable date: \"99/01/01\"")
.hasNoCause();
}
@Test
void testBindDateArray() {
MutablePropertyValues propertyValues = new MutablePropertyValues();
@ -330,7 +360,10 @@ public class DateFormattingTests { @@ -330,7 +360,10 @@ public class DateFormattingTests {
.hasMessageContainingAll(
"Unable to parse date time value \"210302\" using configuration from",
"@org.springframework.format.annotation.DateTimeFormat",
"yyyy-MM-dd", "M/d/yy", "yyyyMMdd", "yyyy.MM.dd");
"yyyy-MM-dd", "M/d/yy", "yyyyMMdd", "yyyy.MM.dd")
.hasCauseInstanceOf(ParseException.class).getCause()
.hasMessageStartingWith("Unparseable date: \"210302\"")
.hasNoCause();
}
}

Loading…
Cancel
Save