From 22d9012081bc5e8da58589e5af8893db8c5361fd Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Mon, 12 Apr 2021 19:55:43 +0200 Subject: [PATCH] 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 --- .../standard/TemporalAccessorParser.java | 2 +- .../standard/DateTimeFormattingTests.java | 37 ++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) 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 9f99f2ecf2..b8dd20fe01 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 105da3d2ae..6aa28756f6 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 { -- GitLab