Skip to content

Commit 46255d3

Browse files
committed
Improve error reporting wrt #1338 to add more info on which property caused the problem
1 parent 75098b7 commit 46255d3

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.fasterxml.jackson.databind.cfg.ContextAttributes;
1414
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
1515
import com.fasterxml.jackson.databind.introspect.Annotated;
16+
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
1617
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
1718
import com.fasterxml.jackson.databind.ser.*;
1819
import com.fasterxml.jackson.databind.ser.impl.FailingSerializer;
@@ -1145,6 +1146,41 @@ public void reportMappingProblem(Throwable t, String message, Object... args) th
11451146
throw mappingException(t, message, args);
11461147
}
11471148

1149+
/**
1150+
* Helper method called to indicate problem in POJO (serialization) definitions or settings
1151+
* regarding specific Java type, unrelated to actual JSON content to map.
1152+
* Default behavior is to construct and throw a {@link JsonMappingException}.
1153+
*
1154+
* @since 2.9
1155+
*/
1156+
public <T> T reportBadTypeDefinition(BeanDescription bean,
1157+
String message, Object... args) throws JsonMappingException {
1158+
if (args != null && args.length > 0) {
1159+
message = String.format(message, args);
1160+
}
1161+
String beanDesc = (bean == null) ? "N/A" : _desc(bean.getType().getGenericSignature());
1162+
throw mappingException("Invalid type definition for type %s: %s",
1163+
beanDesc, message);
1164+
}
1165+
1166+
/**
1167+
* Helper method called to indicate problem in POJO (serialization) definitions or settings
1168+
* regarding specific property (of a type), unrelated to actual JSON content to map.
1169+
* Default behavior is to construct and throw a {@link JsonMappingException}.
1170+
*
1171+
* @since 2.9
1172+
*/
1173+
public <T> T reportBadPropertyDefinition(BeanDescription bean, BeanPropertyDefinition prop,
1174+
String message, Object... args) throws JsonMappingException {
1175+
if (args != null && args.length > 0) {
1176+
message = String.format(message, args);
1177+
}
1178+
String propName = (prop == null) ? "N/A" : _desc(prop.getName());
1179+
String beanDesc = (bean == null) ? "N/A" : _desc(bean.getType().getGenericSignature());
1180+
throw mappingException("Invalid definition for property %s (of type %s): %s",
1181+
propName, beanDesc, message);
1182+
}
1183+
11481184
/**
11491185
* @since 2.8
11501186
*/
@@ -1304,6 +1340,13 @@ protected JsonSerializer<Object> _handleResolvable(JsonSerializer<?> ser)
13041340
/**********************************************************
13051341
*/
13061342

1343+
protected String _desc(Object value) {
1344+
if (value == null) {
1345+
return "N/A";
1346+
}
1347+
return "'"+value+"'";
1348+
}
1349+
13071350
protected final DateFormat _dateFormat()
13081351
{
13091352
if (_dateFormat != null) {

src/main/java/com/fasterxml/jackson/databind/ser/BeanSerializerFactory.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,17 @@ public JsonSerializer<Object> createSerializer(SerializerProvider prov,
143143
boolean staticTyping;
144144
// Next: we may have annotations that further indicate actual type to use (a super type)
145145
final AnnotationIntrospector intr = config.getAnnotationIntrospector();
146-
JavaType type = (intr == null) ? origType
147-
: intr.refineSerializationType(config, beanDesc.getClassInfo(), origType);
146+
JavaType type;
147+
148+
if (intr == null) {
149+
type = origType;
150+
} else {
151+
try {
152+
type = intr.refineSerializationType(config, beanDesc.getClassInfo(), origType);
153+
} catch (JsonMappingException e) {
154+
return prov.reportBadTypeDefinition(beanDesc, e.getMessage());
155+
}
156+
}
148157
if (type == origType) { // no changes, won't force static typing
149158
staticTyping = false;
150159
} else { // changes; assume static typing; plus, need to re-introspect if class differs

src/main/java/com/fasterxml/jackson/databind/ser/PropertyBuilder.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,12 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov,
9494
throws JsonMappingException
9595
{
9696
// do we have annotation that forces type to use (to declared type or its super type)?
97-
JavaType serializationType = findSerializationType(am, defaultUseStaticTyping, declaredType);
97+
JavaType serializationType;
98+
try {
99+
serializationType = findSerializationType(am, defaultUseStaticTyping, declaredType);
100+
} catch (JsonMappingException e) {
101+
return prov.reportBadPropertyDefinition(_beanDesc, propDef, e.getMessage());
102+
}
98103

99104
// Container types can have separate type serializers for content (value / element) type
100105
if (contentTypeSer != null) {
@@ -109,13 +114,13 @@ protected BeanPropertyWriter buildWriter(SerializerProvider prov,
109114
JavaType ct = serializationType.getContentType();
110115
// Not exactly sure why, but this used to occur; better check explicitly:
111116
if (ct == null) {
112-
throw new IllegalStateException("Problem trying to create BeanPropertyWriter for property '"
113-
+propDef.getName()+"' (of type "+_beanDesc.getType()+"); serialization type "+serializationType+" has no content");
117+
prov.reportBadPropertyDefinition(_beanDesc, propDef,
118+
"serialization type "+serializationType+" has no content");
114119
}
115120
serializationType = serializationType.withContentTypeHandler(contentTypeSer);
116121
ct = serializationType.getContentType();
117122
}
118-
123+
119124
Object valueToSuppress = null;
120125
boolean suppressNulls = false;
121126

@@ -221,6 +226,7 @@ protected JavaType findSerializationType(Annotated a, boolean useStaticTyping, J
221226
throws JsonMappingException
222227
{
223228
JavaType secondary = _annotationIntrospector.refineSerializationType(_config, a, declaredType);
229+
224230
// 11-Oct-2015, tatu: As of 2.7, not 100% sure following checks are needed. But keeping
225231
// for now, just in case
226232
if (secondary != declaredType) {

0 commit comments

Comments
 (0)