Skip to content

Commit 4b9bfd0

Browse files
committed
Working on standardizing parsing error handling
1 parent 88941d2 commit 4b9bfd0

File tree

8 files changed

+41
-37
lines changed

8 files changed

+41
-37
lines changed

src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,8 @@ public JsonMappingException instantiationException(Class<?> instClass, Throwable
10241024
@Deprecated
10251025
public JsonMappingException instantiationException(Class<?> instClass, String msg) {
10261026
return JsonMappingException.from(_parser,
1027-
String.format("Can not construct instance of %s, problem: %s", instClass.getName(), msg));
1027+
String.format("Can not construct instance of %s: %s",
1028+
instClass.getName(), msg));
10281029
}
10291030

10301031
/**
@@ -1040,9 +1041,10 @@ public JsonMappingException instantiationException(Class<?> instClass, String ms
10401041
* @deprecated Since 2.8 use {@link #reportWeirdStringException} instead
10411042
*/
10421043
@Deprecated
1043-
public JsonMappingException weirdStringException(String value, Class<?> instClass, String msg) {
1044+
public JsonMappingException weirdStringException(String value, Class<?> instClass,
1045+
String msg) {
10441046
return InvalidFormatException.from(_parser,
1045-
String.format("Can not construct instance of %s from String value (%s): %s",
1047+
String.format("Can not deserialize value of type %s from String %s: %s",
10461048
instClass.getName(), _quotedString(value), msg),
10471049
value, instClass);
10481050
}
@@ -1054,9 +1056,10 @@ public JsonMappingException weirdStringException(String value, Class<?> instClas
10541056
* @deprecated Since 2.8 use {@link #reportWeirdNumberException} instead
10551057
*/
10561058
@Deprecated
1057-
public JsonMappingException weirdNumberException(Number value, Class<?> instClass, String msg) {
1059+
public JsonMappingException weirdNumberException(Number value, Class<?> instClass,
1060+
String msg) {
10581061
return InvalidFormatException.from(_parser,
1059-
String.format("Can not construct instance of %s from number value (%s): %s",
1062+
String.format("Can not deserialize value of type %s from number %s: %s",
10601063
instClass.getName(), String.valueOf(value), msg),
10611064
value, instClass);
10621065
}
@@ -1071,7 +1074,7 @@ public JsonMappingException weirdNumberException(Number value, Class<?> instClas
10711074
@Deprecated
10721075
public JsonMappingException weirdKeyException(Class<?> keyClass, String keyValue, String msg) {
10731076
return InvalidFormatException.from(_parser,
1074-
String.format("Can not construct Map key of type %s from String (%s): %s",
1077+
String.format("Can not deserialize Map key of type %s from String %s: %s",
10751078
keyClass.getName(), _quotedString(keyValue), msg),
10761079
keyValue, keyClass);
10771080
}

src/main/java/com/fasterxml/jackson/databind/deser/std/DateDeserializers.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
import java.util.*;
77

88
import com.fasterxml.jackson.annotation.JsonFormat;
9-
109
import com.fasterxml.jackson.core.JsonParser;
1110
import com.fasterxml.jackson.core.JsonToken;
12-
1311
import com.fasterxml.jackson.databind.BeanProperty;
1412
import com.fasterxml.jackson.databind.DeserializationContext;
1513
import com.fasterxml.jackson.databind.DeserializationFeature;
@@ -155,8 +153,9 @@ protected java.util.Date _parseDate(JsonParser p, DeserializationContext ctxt)
155153
try {
156154
return _customFormat.parse(str);
157155
} catch (ParseException e) {
158-
throw new IllegalArgumentException("Failed to parse Date value '"+str
159-
+"' (format: \""+_formatString+"\"): "+e.getMessage());
156+
ctxt.reportWeirdStringException(str, handledType(),
157+
"expected format \"%s\"", _formatString);
158+
return null;
160159
}
161160
}
162161
}
@@ -180,7 +179,7 @@ protected java.util.Date _parseDate(JsonParser p, DeserializationContext ctxt)
180179
/* Deserializer implementations for Date types
181180
/**********************************************************
182181
*/
183-
182+
184183
@JacksonStdImpl
185184
public static class CalendarDeserializer extends DateBasedDeserializer<Calendar>
186185
{
@@ -242,6 +241,7 @@ public Calendar deserialize(JsonParser p, DeserializationContext ctxt) throws IO
242241
* {@link DeserializationContext#parseDate} that this basic
243242
* deserializer calls.
244243
*/
244+
@JacksonStdImpl
245245
public static class DateDeserializer extends DateBasedDeserializer<Date>
246246
{
247247
public final static DateDeserializer instance = new DateDeserializer();

src/main/java/com/fasterxml/jackson/databind/deser/std/EnumDeserializer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
88
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
99
import com.fasterxml.jackson.databind.deser.ValueInstantiator;
10-
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
1110
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
1211
import com.fasterxml.jackson.databind.util.ClassUtil;
1312
import com.fasterxml.jackson.databind.util.CompactStringObjectMap;
@@ -134,6 +133,7 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
134133
int index = p.getIntValue();
135134
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)) {
136135
_failOnNumber(ctxt, p, index);
136+
return null;
137137
}
138138
if (index >= 0 && index <= _enumsByIndex.length) {
139139
return _enumsByIndex[index];
@@ -175,6 +175,7 @@ private final Object _deserializeAltString(JsonParser p, DeserializationContext
175175
int ix = Integer.parseInt(name);
176176
if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)) {
177177
_failOnNumber(ctxt, p, ix);
178+
return null;
178179
}
179180
if (ix >= 0 && ix <= _enumsByIndex.length) {
180181
return _enumsByIndex[ix];
@@ -216,10 +217,9 @@ protected Object _deserializeOther(JsonParser p, DeserializationContext ctxt) th
216217
protected void _failOnNumber(DeserializationContext ctxt, JsonParser p, int index)
217218
throws IOException
218219
{
219-
throw InvalidFormatException.from(p,
220-
String.format("Not allowed to deserialize Enum value out of JSON number (%d): disable DeserializationConfig.DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS to allow",
221-
index),
222-
index, _enumClass());
220+
ctxt.reportWeirdNumberException(index, _enumClass(),
221+
"not allowed to deserialize Enum value out of number: disable DeserializationConfig.DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS to allow"
222+
);
223223
}
224224

225225
protected Class<?> _enumClass() {

src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ protected java.util.Date _parseDate(JsonParser p, DeserializationContext ctxt)
780780
return (java.util.Date) getNullValue(ctxt);
781781
}
782782
if (t == JsonToken.VALUE_STRING) {
783-
return _parseDate(p.getText(), ctxt);
783+
return _parseDate(p.getText().trim(), ctxt);
784784
}
785785
// [databind#381]
786786
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {

src/main/java/com/fasterxml/jackson/databind/deser/std/UUIDDeserializer.java

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ protected UUID _deserialize(String id, DeserializationContext ctxt) throws IOExc
3939
byte[] stuff = Base64Variants.getDefaultVariant().decode(id);
4040
return _fromBytes(stuff, ctxt);
4141
}
42-
_badFormat(id, ctxt);
42+
return _badFormat(id, ctxt);
4343
}
4444

4545
// verify hyphens first:
@@ -73,27 +73,26 @@ protected UUID _deserializeEmbedded(Object ob, DeserializationContext ctxt) thro
7373
return null; // never gets here
7474
}
7575

76-
private void _badFormat(String uuidStr, DeserializationContext ctxt)
76+
private UUID _badFormat(String uuidStr, DeserializationContext ctxt)
7777
throws JsonMappingException
7878
{
79-
throw InvalidFormatException.from(ctxt.getParser(),
80-
String.format("UUID has to be represented by standard 36-char representation: input String '%s'",
81-
uuidStr),
82-
uuidStr, handledType());
79+
ctxt.reportWeirdStringException(uuidStr, handledType(),
80+
"UUID has to be represented by standard 36-char representation");
81+
return null;
8382
}
84-
85-
static int intFromChars(String str, int index, DeserializationContext ctxt) throws JsonMappingException {
83+
84+
int intFromChars(String str, int index, DeserializationContext ctxt) throws JsonMappingException {
8685
return (byteFromChars(str, index, ctxt) << 24)
8786
+ (byteFromChars(str, index+2, ctxt) << 16)
8887
+ (byteFromChars(str, index+4, ctxt) << 8)
8988
+ byteFromChars(str, index+6, ctxt);
9089
}
9190

92-
static int shortFromChars(String str, int index, DeserializationContext ctxt) throws JsonMappingException {
91+
int shortFromChars(String str, int index, DeserializationContext ctxt) throws JsonMappingException {
9392
return (byteFromChars(str, index, ctxt) << 8) + byteFromChars(str, index+2, ctxt);
9493
}
9594

96-
static int byteFromChars(String str, int index, DeserializationContext ctxt) throws JsonMappingException
95+
int byteFromChars(String str, int index, DeserializationContext ctxt) throws JsonMappingException
9796
{
9897
final char c1 = str.charAt(index);
9998
final char c2 = str.charAt(index+1);
@@ -110,11 +109,11 @@ static int byteFromChars(String str, int index, DeserializationContext ctxt) thr
110109
return _badChar(str, index+1, ctxt, c2);
111110
}
112111

113-
static int _badChar(String uuidStr, int index, DeserializationContext ctxt, char c) throws JsonMappingException {
114-
String msg = String.format(
115-
"Non-hex character '%c' (value 0x%s), not valid for UUID String: input String '%s'",
116-
c, Integer.toHexString(c), uuidStr);
117-
throw InvalidFormatException.from(ctxt.getParser(), msg, uuidStr, UUID.class);
112+
int _badChar(String uuidStr, int index, DeserializationContext ctxt, char c) throws JsonMappingException {
113+
ctxt.reportWeirdStringException(uuidStr, handledType(),
114+
"Non-hex character '%c' (value 0x%s), not valid for UUID String",
115+
c, Integer.toHexString(c));
116+
return 0;
118117
}
119118

120119
private UUID _fromBytes(byte[] bytes, DeserializationContext ctxt) throws JsonMappingException {

src/test/java/com/fasterxml/jackson/databind/convert/TestBeanConversions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public void testErrorReporting() throws Exception
124124
try {
125125
MAPPER.readValue("{\"boolProp\":\"foobar\"}", BooleanBean.class);
126126
} catch (JsonMappingException e) {
127-
verifyException(e, "from String value (\"foobar\")");
127+
verifyException(e, "Can not deserialize value of type boolean from String");
128128
}
129129
}
130130

src/test/java/com/fasterxml/jackson/databind/deser/EnumDeserializationTest.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,17 @@ public void testNumbersToEnums() throws Exception
280280
value = r.readValue("1");
281281
fail("Expected an error");
282282
} catch (JsonMappingException e) {
283-
verifyException(e, "Not allowed to deserialize Enum value out of JSON number");
283+
verifyException(e, "Can not deserialize");
284+
verifyException(e, "not allowed to deserialize Enum value out of number: disable");
284285
}
285286

286287
// and [databind#684]
287288
try {
288289
value = r.readValue(quote("1"));
289290
fail("Expected an error");
290291
} catch (JsonMappingException e) {
291-
verifyException(e, "Not allowed to deserialize Enum value out of JSON number");
292+
verifyException(e, "Can not deserialize");
293+
verifyException(e, "not allowed to deserialize Enum value out of number: disable");
292294
}
293295
}
294296

@@ -359,7 +361,7 @@ public void testDoNotAllowUnknownEnumValuesAsMapKeysWhenReadAsNullDisabled() thr
359361
MAPPER.readValue("{\"map\":{\"NO-SUCH-VALUE\":\"val\"}}", ClassWithEnumMapKey.class);
360362
fail("Expected an exception for bogus enum value...");
361363
} catch (JsonMappingException jex) {
362-
verifyException(jex, "Can not construct Map key");
364+
verifyException(jex, "Can not deserialize Map key of type com.fasterxml.jackson.databind.deser");
363365
}
364366
}
365367

src/test/java/com/fasterxml/jackson/databind/deser/TestDateDeserialization.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ public void testInvalidFormat() throws Exception
516516
MAPPER.readValue(quote("foobar"), Date.class);
517517
fail("Should have failed with an exception");
518518
} catch (InvalidFormatException e) {
519-
verifyException(e, "Can not construct instance");
519+
verifyException(e, "Can not deserialize value of type java.util.Date from String");
520520
assertEquals("foobar", e.getValue());
521521
assertEquals(Date.class, e.getTargetType());
522522
} catch (Exception e) {

0 commit comments

Comments
 (0)