diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/TemporalAccessorParser.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/TemporalAccessorParser.java index 9f99f2ecf23368d6e9116157f3977a88c894e507..b8dd20fe01910536fef842a84ced1809722475d5 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/TemporalAccessorParser.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/TemporalAccessorParser.java @@ -101,7 +101,7 @@ public final class TemporalAccessorParser implements Parser { if (this.source != null) { throw new DateTimeParseException( String.format("Unable to parse date time value \"%s\" using configuration from %s", text, this.source), - text, ex.getErrorIndex()); + text, ex.getErrorIndex(), ex); } // else rethrow original exception throw ex; diff --git a/spring-context/src/test/java/org/springframework/format/datetime/standard/DateTimeFormattingTests.java b/spring-context/src/test/java/org/springframework/format/datetime/standard/DateTimeFormattingTests.java index 105da3d2ae202881deee3d40d160e5bb0ddc52fc..6aa28756f68647c420871ef786eb7da6afdd7ea1 100644 --- a/spring-context/src/test/java/org/springframework/format/datetime/standard/DateTimeFormattingTests.java +++ b/spring-context/src/test/java/org/springframework/format/datetime/standard/DateTimeFormattingTests.java @@ -16,6 +16,7 @@ package org.springframework.format.datetime.standard; +import java.time.DateTimeException; import java.time.Duration; import java.time.Instant; import java.time.LocalDate; @@ -320,6 +321,35 @@ class DateTimeFormattingTests { assertThat(binder.getBindingResult().getFieldValue("isoLocalDate")).isEqualTo("2009-10-31"); } + @Test + void isoLocalDateWithInvalidFormat() { + MutablePropertyValues propertyValues = new MutablePropertyValues(); + String propertyName = "isoLocalDate"; + propertyValues.add(propertyName, "2009-31-10"); + binder.bind(propertyValues); + BindingResult bindingResult = binder.getBindingResult(); + assertThat(bindingResult.getErrorCount()).isEqualTo(1); + FieldError fieldError = bindingResult.getFieldError(propertyName); + assertThat(fieldError.unwrap(TypeMismatchException.class)) + .hasMessageContaining("for property 'isoLocalDate'") + .hasCauseInstanceOf(ConversionFailedException.class).getCause() + .hasMessageContaining("for value '2009-31-10'") + .hasCauseInstanceOf(IllegalArgumentException.class).getCause() + .hasMessageContaining("Parse attempt failed for value [2009-31-10]") + .hasCauseInstanceOf(DateTimeParseException.class).getCause() + // Unable to parse date time value "2009-31-10" using configuration from + // @org.springframework.format.annotation.DateTimeFormat(pattern=, style=SS, iso=DATE, fallbackPatterns=[]) + .hasMessageContainingAll( + "Unable to parse date time value \"2009-31-10\" using configuration from", + "@org.springframework.format.annotation.DateTimeFormat", + "iso=DATE", "fallbackPatterns=[]") + .hasCauseInstanceOf(DateTimeParseException.class).getCause() + .hasMessageStartingWith("Text '2009-31-10'") + .hasCauseInstanceOf(DateTimeException.class).getCause() + .hasMessageContaining("Invalid value for MonthOfYear (valid values 1 - 12): 31") + .hasNoCause(); + } + @Test void testBindISOTime() { MutablePropertyValues propertyValues = new MutablePropertyValues(); @@ -519,9 +549,12 @@ class DateTimeFormattingTests { .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(DateTimeParseException.class).getCause() + .hasMessageStartingWith("Text '210302'") + .hasNoCause(); } -} + } public static class DateTimeBean {