Skip to content

Commit 22d9012

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. This commit ensures that the original DateTimeParseException is set as the cause for any newly created DateTimeParseException, thereby retaining the original exception as the root cause. Closes gh-26777
1 parent 327e761 commit 22d9012

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public TemporalAccessor parse(String text, Locale locale) throws ParseException
101101
if (this.source != null) {
102102
throw new DateTimeParseException(
103103
String.format("Unable to parse date time value \"%s\" using configuration from %s", text, this.source),
104-
text, ex.getErrorIndex());
104+
text, ex.getErrorIndex(), ex);
105105
}
106106
// else rethrow original exception
107107
throw ex;

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

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.format.datetime.standard;
1818

19+
import java.time.DateTimeException;
1920
import java.time.Duration;
2021
import java.time.Instant;
2122
import java.time.LocalDate;
@@ -320,6 +321,35 @@ void testBindISODate() {
320321
assertThat(binder.getBindingResult().getFieldValue("isoLocalDate")).isEqualTo("2009-10-31");
321322
}
322323

324+
@Test
325+
void isoLocalDateWithInvalidFormat() {
326+
MutablePropertyValues propertyValues = new MutablePropertyValues();
327+
String propertyName = "isoLocalDate";
328+
propertyValues.add(propertyName, "2009-31-10");
329+
binder.bind(propertyValues);
330+
BindingResult bindingResult = binder.getBindingResult();
331+
assertThat(bindingResult.getErrorCount()).isEqualTo(1);
332+
FieldError fieldError = bindingResult.getFieldError(propertyName);
333+
assertThat(fieldError.unwrap(TypeMismatchException.class))
334+
.hasMessageContaining("for property 'isoLocalDate'")
335+
.hasCauseInstanceOf(ConversionFailedException.class).getCause()
336+
.hasMessageContaining("for value '2009-31-10'")
337+
.hasCauseInstanceOf(IllegalArgumentException.class).getCause()
338+
.hasMessageContaining("Parse attempt failed for value [2009-31-10]")
339+
.hasCauseInstanceOf(DateTimeParseException.class).getCause()
340+
// Unable to parse date time value "2009-31-10" using configuration from
341+
// @org.springframework.format.annotation.DateTimeFormat(pattern=, style=SS, iso=DATE, fallbackPatterns=[])
342+
.hasMessageContainingAll(
343+
"Unable to parse date time value \"2009-31-10\" using configuration from",
344+
"@org.springframework.format.annotation.DateTimeFormat",
345+
"iso=DATE", "fallbackPatterns=[]")
346+
.hasCauseInstanceOf(DateTimeParseException.class).getCause()
347+
.hasMessageStartingWith("Text '2009-31-10'")
348+
.hasCauseInstanceOf(DateTimeException.class).getCause()
349+
.hasMessageContaining("Invalid value for MonthOfYear (valid values 1 - 12): 31")
350+
.hasNoCause();
351+
}
352+
323353
@Test
324354
void testBindISOTime() {
325355
MutablePropertyValues propertyValues = new MutablePropertyValues();
@@ -519,9 +549,12 @@ void patternLocalDateWithUnsupportedPattern() {
519549
.hasMessageContainingAll(
520550
"Unable to parse date time value \"210302\" using configuration from",
521551
"@org.springframework.format.annotation.DateTimeFormat",
522-
"yyyy-MM-dd", "M/d/yy", "yyyyMMdd", "yyyy.MM.dd");
552+
"yyyy-MM-dd", "M/d/yy", "yyyyMMdd", "yyyy.MM.dd")
553+
.hasCauseInstanceOf(DateTimeParseException.class).getCause()
554+
.hasMessageStartingWith("Text '210302'")
555+
.hasNoCause();
523556
}
524-
}
557+
}
525558

526559

527560
public static class DateTimeBean {

0 commit comments

Comments
 (0)