8025718: Enhance error messages for parsing
Add values and types to exception messages Reviewed-by: lancea
This commit is contained in:
parent
c9982055b4
commit
242f0dd3c2
@ -187,7 +187,12 @@ public enum DayOfWeek implements TemporalAccessor, TemporalAdjuster {
|
||||
if (temporal instanceof DayOfWeek) {
|
||||
return (DayOfWeek) temporal;
|
||||
}
|
||||
return of(temporal.get(DAY_OF_WEEK));
|
||||
try {
|
||||
return of(temporal.get(DAY_OF_WEEK));
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to obtain DayOfWeek from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
@ -366,9 +366,14 @@ public final class Instant
|
||||
return (Instant) temporal;
|
||||
}
|
||||
Objects.requireNonNull(temporal, "temporal");
|
||||
long instantSecs = temporal.getLong(INSTANT_SECONDS);
|
||||
int nanoOfSecond = temporal.get(NANO_OF_SECOND);
|
||||
return Instant.ofEpochSecond(instantSecs, nanoOfSecond);
|
||||
try {
|
||||
long instantSecs = temporal.getLong(INSTANT_SECONDS);
|
||||
int nanoOfSecond = temporal.get(NANO_OF_SECOND);
|
||||
return Instant.ofEpochSecond(instantSecs, nanoOfSecond);
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to obtain Instant from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
@ -356,7 +356,8 @@ public final class LocalDate
|
||||
Objects.requireNonNull(temporal, "temporal");
|
||||
LocalDate date = temporal.query(TemporalQuery.localDate());
|
||||
if (date == null) {
|
||||
throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " + temporal.getClass());
|
||||
throw new DateTimeException("Unable to obtain LocalDate from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName());
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
@ -449,7 +449,8 @@ public final class LocalDateTime
|
||||
LocalTime time = LocalTime.from(temporal);
|
||||
return new LocalDateTime(date, time);
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: " + temporal.getClass(), ex);
|
||||
throw new DateTimeException("Unable to obtain LocalDateTime from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,8 @@ public final class LocalTime
|
||||
Objects.requireNonNull(temporal, "temporal");
|
||||
LocalTime time = temporal.query(TemporalQuery.localTime());
|
||||
if (time == null) {
|
||||
throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " + temporal.getClass());
|
||||
throw new DateTimeException("Unable to obtain LocalTime from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName());
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
@ -217,7 +217,8 @@ public enum Month implements TemporalAccessor, TemporalAdjuster {
|
||||
}
|
||||
return of(temporal.get(MONTH_OF_YEAR));
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to obtain Month from TemporalAccessor: " + temporal.getClass(), ex);
|
||||
throw new DateTimeException("Unable to obtain Month from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +266,8 @@ public final class MonthDay
|
||||
}
|
||||
return of(temporal.get(MONTH_OF_YEAR), temporal.get(DAY_OF_MONTH));
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to obtain MonthDay from TemporalAccessor: " + temporal.getClass(), ex);
|
||||
throw new DateTimeException("Unable to obtain MonthDay from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,8 +347,8 @@ public final class OffsetDateTime
|
||||
if (temporal instanceof OffsetDateTime) {
|
||||
return (OffsetDateTime) temporal;
|
||||
}
|
||||
ZoneOffset offset = ZoneOffset.from(temporal);
|
||||
try {
|
||||
ZoneOffset offset = ZoneOffset.from(temporal);
|
||||
try {
|
||||
LocalDateTime ldt = LocalDateTime.from(temporal);
|
||||
return OffsetDateTime.of(ldt, offset);
|
||||
@ -357,7 +357,8 @@ public final class OffsetDateTime
|
||||
return OffsetDateTime.ofInstant(instant, offset);
|
||||
}
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to obtain OffsetDateTime from TemporalAccessor: " + temporal.getClass(), ex);
|
||||
throw new DateTimeException("Unable to obtain OffsetDateTime from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,7 +284,8 @@ public final class OffsetTime
|
||||
ZoneOffset offset = ZoneOffset.from(temporal);
|
||||
return new OffsetTime(time, offset);
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to obtain OffsetTime from TemporalAccessor: " + temporal.getClass(), ex);
|
||||
throw new DateTimeException("Unable to obtain OffsetTime from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,8 @@ public final class Year
|
||||
}
|
||||
return of(temporal.get(YEAR));
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to obtain Year from TemporalAccessor: " + temporal.getClass(), ex);
|
||||
throw new DateTimeException("Unable to obtain Year from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,8 @@ public final class YearMonth
|
||||
}
|
||||
return of(temporal.get(YEAR), temporal.get(MONTH_OF_YEAR));
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to obtain YearMonth from TemporalAccessor: " + temporal.getClass(), ex);
|
||||
throw new DateTimeException("Unable to obtain YearMonth from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -504,7 +504,8 @@ public abstract class ZoneId implements Serializable {
|
||||
public static ZoneId from(TemporalAccessor temporal) {
|
||||
ZoneId obj = temporal.query(TemporalQuery.zone());
|
||||
if (obj == null) {
|
||||
throw new DateTimeException("Unable to obtain ZoneId from TemporalAccessor: " + temporal.getClass());
|
||||
throw new DateTimeException("Unable to obtain ZoneId from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
@ -336,7 +336,8 @@ public final class ZoneOffset
|
||||
Objects.requireNonNull(temporal, "temporal");
|
||||
ZoneOffset offset = temporal.query(TemporalQuery.offset());
|
||||
if (offset == null) {
|
||||
throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " + temporal.getClass());
|
||||
throw new DateTimeException("Unable to obtain ZoneOffset from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName());
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
@ -553,7 +553,8 @@ public final class ZonedDateTime
|
||||
return of(ldt, zone);
|
||||
}
|
||||
} catch (DateTimeException ex) {
|
||||
throw new DateTimeException("Unable to create ZonedDateTime from TemporalAccessor: " + temporal.getClass(), ex);
|
||||
throw new DateTimeException("Unable to obtain ZonedDateTime from TemporalAccessor: " +
|
||||
temporal + " of type " + temporal.getClass().getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -588,11 +588,23 @@ final class Parsed implements TemporalAccessor {
|
||||
//-----------------------------------------------------------------------
|
||||
@Override
|
||||
public String toString() {
|
||||
String str = fieldValues.toString() + "," + chrono + "," + zone;
|
||||
if (date != null || time != null) {
|
||||
str += " resolved to " + date + "," + time;
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
buf.append(fieldValues).append(',').append(chrono);
|
||||
if (zone != null) {
|
||||
buf.append(',').append(zone);
|
||||
}
|
||||
return str;
|
||||
if (date != null || time != null) {
|
||||
buf.append(" resolved to ");
|
||||
if (date != null) {
|
||||
buf.append(date);
|
||||
if (time != null) {
|
||||
buf.append('T').append(time);
|
||||
}
|
||||
} else {
|
||||
buf.append(time);
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -61,12 +61,32 @@ package test.java.time.format;
|
||||
|
||||
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
|
||||
import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import java.time.format.DecimalStyle;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.Month;
|
||||
import java.time.MonthDay;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.OffsetTime;
|
||||
import java.time.Year;
|
||||
import java.time.YearMonth;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.chrono.ThaiBuddhistChronology;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeFormatterBuilder;
|
||||
import java.time.format.DecimalStyle;
|
||||
import java.time.format.SignStyle;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@ -87,4 +107,93 @@ public class TestDateTimeFormatter {
|
||||
assertSame(test, base);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_parse_errorMessage() throws Exception {
|
||||
assertGoodErrorDate(DayOfWeek::from, "DayOfWeek");
|
||||
assertGoodErrorDate(Month::from, "Month");
|
||||
assertGoodErrorDate(YearMonth::from, "YearMonth");
|
||||
assertGoodErrorDate(MonthDay::from, "MonthDay");
|
||||
assertGoodErrorDate(LocalDate::from, "LocalDate");
|
||||
assertGoodErrorDate(LocalTime::from, "LocalTime");
|
||||
assertGoodErrorDate(LocalDateTime::from, "LocalDateTime");
|
||||
assertGoodErrorDate(OffsetTime::from, "OffsetTime");
|
||||
assertGoodErrorDate(OffsetDateTime::from, "OffsetDateTime");
|
||||
assertGoodErrorDate(ZonedDateTime::from, "ZonedDateTime");
|
||||
assertGoodErrorDate(Instant::from, "Instant");
|
||||
assertGoodErrorDate(ZoneOffset::from, "ZoneOffset");
|
||||
assertGoodErrorDate(ZoneId::from, "ZoneId");
|
||||
assertGoodErrorDate(ThaiBuddhistChronology.INSTANCE::date, "");
|
||||
|
||||
assertGoodErrorTime(DayOfWeek::from, "DayOfWeek");
|
||||
assertGoodErrorTime(Month::from, "Month");
|
||||
assertGoodErrorTime(Year::from, "Year");
|
||||
assertGoodErrorTime(YearMonth::from, "YearMonth");
|
||||
assertGoodErrorTime(MonthDay::from, "MonthDay");
|
||||
assertGoodErrorTime(LocalDate::from, "LocalDate");
|
||||
assertGoodErrorTime(LocalTime::from, "LocalTime");
|
||||
assertGoodErrorTime(LocalDateTime::from, "LocalDateTime");
|
||||
assertGoodErrorTime(OffsetTime::from, "OffsetTime");
|
||||
assertGoodErrorTime(OffsetDateTime::from, "OffsetDateTime");
|
||||
assertGoodErrorTime(ZonedDateTime::from, "ZonedDateTime");
|
||||
assertGoodErrorTime(Instant::from, "Instant");
|
||||
assertGoodErrorTime(ZoneOffset::from, "ZoneOffset");
|
||||
assertGoodErrorTime(ZoneId::from, "ZoneId");
|
||||
assertGoodErrorTime(ThaiBuddhistChronology.INSTANCE::date, "");
|
||||
}
|
||||
|
||||
private void assertGoodErrorDate(Function<TemporalAccessor, Object> function, String expectedText) {
|
||||
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-mm-dd");
|
||||
TemporalAccessor temporal = f.parse("2010-06-30");
|
||||
try {
|
||||
function.apply(temporal);
|
||||
fail("Should have failed");
|
||||
} catch (DateTimeException ex) {
|
||||
String msg = ex.getMessage();
|
||||
assertTrue(msg.contains(expectedText), msg);
|
||||
assertTrue(msg.contains("Year"), msg);
|
||||
assertTrue(msg.contains("MinuteOfHour"), msg);
|
||||
assertTrue(msg.contains("DayOfMonth"), msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertGoodErrorTime(Function<TemporalAccessor, Object> function, String expectedText) {
|
||||
DateTimeFormatter f = DateTimeFormatter.ofPattern("HH:MM:ss");
|
||||
TemporalAccessor temporal = f.parse("11:30:56");
|
||||
try {
|
||||
function.apply(temporal);
|
||||
fail("Should have failed");
|
||||
} catch (DateTimeException ex) {
|
||||
String msg = ex.getMessage();
|
||||
assertTrue(msg.contains(expectedText), msg);
|
||||
assertTrue(msg.contains("HourOfDay"), msg);
|
||||
assertTrue(msg.contains("MonthOfYear"), msg);
|
||||
assertTrue(msg.contains("SecondOfMinute"), msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_parsed_toString_resolvedTime() {
|
||||
DateTimeFormatter f = DateTimeFormatter.ofPattern("HH:mm:ss");
|
||||
TemporalAccessor temporal = f.parse("11:30:56");
|
||||
String msg = temporal.toString();
|
||||
assertTrue(msg.contains("11:30:56"), msg);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_parsed_toString_resolvedDate() {
|
||||
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
TemporalAccessor temporal = f.parse("2010-06-30");
|
||||
String msg = temporal.toString();
|
||||
assertTrue(msg.contains("2010-06-30"), msg);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_parsed_toString_resolvedDateTime() {
|
||||
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
TemporalAccessor temporal = f.parse("2010-06-30 11:30:56");
|
||||
String msg = temporal.toString();
|
||||
assertTrue(msg.contains("2010-06-30"), msg);
|
||||
assertTrue(msg.contains("11:30:56"), msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user