diff --git a/spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java b/spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java index d69e9c15e5fb..2158a4684fa9 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/DateFormatter.java @@ -219,9 +219,11 @@ public Date parse(String text, Locale locale) throws ParseException { } } 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; diff --git a/spring-context/src/test/java/org/springframework/format/datetime/DateFormattingTests.java b/spring-context/src/test/java/org/springframework/format/datetime/DateFormattingTests.java index ebfbc694dc51..15342c69b6ad 100644 --- a/spring-context/src/test/java/org/springframework/format/datetime/DateFormattingTests.java +++ b/spring-context/src/test/java/org/springframework/format/datetime/DateFormattingTests.java @@ -119,6 +119,36 @@ void testBindDateAnnotated() { 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 @@ void patternDateWithUnsupportedPattern() { .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(); } }