Skip to content

Commit 0f31830

Browse files
committed
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
1 parent 5d297c6 commit 0f31830

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,11 @@ public Date parse(String text, Locale locale) throws ParseException {
219219
}
220220
}
221221
if (this.source != null) {
222-
throw new ParseException(
222+
ParseException parseException = new ParseException(
223223
String.format("Unable to parse date time value \"%s\" using configuration from %s", text, this.source),
224224
ex.getErrorOffset());
225+
parseException.initCause(ex);
226+
throw parseException;
225227
}
226228
// else rethrow original exception
227229
throw ex;

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,36 @@ void testBindDateAnnotated() {
119119
assertThat(binder.getBindingResult().getFieldValue("styleDate")).isEqualTo("10/31/09");
120120
}
121121

122+
@Test
123+
void styleDateWithInvalidFormat() {
124+
String propertyName = "styleDate";
125+
String propertyValue = "99/01/01";
126+
MutablePropertyValues propertyValues = new MutablePropertyValues();
127+
propertyValues.add(propertyName, propertyValue);
128+
binder.bind(propertyValues);
129+
BindingResult bindingResult = binder.getBindingResult();
130+
assertThat(bindingResult.getErrorCount()).isEqualTo(1);
131+
FieldError fieldError = bindingResult.getFieldError(propertyName);
132+
TypeMismatchException exception = fieldError.unwrap(TypeMismatchException.class);
133+
exception.printStackTrace(System.err);
134+
assertThat(exception)
135+
.hasMessageContaining("for property 'styleDate'")
136+
.hasCauseInstanceOf(ConversionFailedException.class).getCause()
137+
.hasMessageContaining("for value '99/01/01'")
138+
.hasCauseInstanceOf(IllegalArgumentException.class).getCause()
139+
.hasMessageContaining("Parse attempt failed for value [99/01/01]")
140+
.hasCauseInstanceOf(ParseException.class).getCause()
141+
// Unable to parse date time value "99/01/01" using configuration from
142+
// @org.springframework.format.annotation.DateTimeFormat(pattern=, style=S-, iso=NONE, fallbackPatterns=[])
143+
.hasMessageContainingAll(
144+
"Unable to parse date time value \"99/01/01\" using configuration from",
145+
"@org.springframework.format.annotation.DateTimeFormat",
146+
"style=S-", "iso=NONE", "fallbackPatterns=[]")
147+
.hasCauseInstanceOf(ParseException.class).getCause()
148+
.hasMessageStartingWith("Unparseable date: \"99/01/01\"")
149+
.hasNoCause();
150+
}
151+
122152
@Test
123153
void testBindDateArray() {
124154
MutablePropertyValues propertyValues = new MutablePropertyValues();
@@ -330,7 +360,10 @@ void patternDateWithUnsupportedPattern() {
330360
.hasMessageContainingAll(
331361
"Unable to parse date time value \"210302\" using configuration from",
332362
"@org.springframework.format.annotation.DateTimeFormat",
333-
"yyyy-MM-dd", "M/d/yy", "yyyyMMdd", "yyyy.MM.dd");
363+
"yyyy-MM-dd", "M/d/yy", "yyyyMMdd", "yyyy.MM.dd")
364+
.hasCauseInstanceOf(ParseException.class).getCause()
365+
.hasMessageStartingWith("Unparseable date: \"210302\"")
366+
.hasNoCause();
334367
}
335368
}
336369

0 commit comments

Comments
 (0)