Skip to content

Commit

Permalink
Fix #1017 (add InvalidTypeIdException)
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed May 11, 2016
1 parent 2d318f6 commit 1ecc6b5
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 12 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Project: jackson-databind
#990: Allow failing on `null` values for creator (add
`DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES`)
(contributed by mkokho@github)
#1017: Add new mapping exception type ('InvalidTypeIdException') for subtype resolution errors
(suggested by natnan@github)
#1082: Can not use static Creator factory methods for `Enum`s, with JsonCreator.Mode.PROPERTIES
(contributed by Lokesh K)
#1084: Change `TypeDeserializerBase` to take `JavaType` for `defaultImpl`, NOT `Class`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
import com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
Expand Down Expand Up @@ -893,12 +894,12 @@ public JavaType handleUnknownTypeId(JavaType baseType, String id,
if (type.isTypeOrSubTypeOf(baseType.getRawClass())) {
return type;
}
throw unknownTypeException(baseType, id,
throw unknownTypeIdException(baseType, id,
"problem handler tried to resolve into non-subtype: "+type);
}
h = h.next();
}
throw unknownTypeException(baseType, id, extraDesc);
throw unknownTypeIdException(baseType, id, extraDesc);
}

/*
Expand Down Expand Up @@ -1072,7 +1073,7 @@ public JsonMappingException mappingException(String msgTemplate, Object... args)
/*
/**********************************************************
/* Methods for constructing semantic exceptions; usually not
/* to be called direclty, call `handleXxx()` instead
/* to be called directly, call `handleXxx()` instead
/**********************************************************
*/

Expand All @@ -1090,17 +1091,20 @@ public JsonMappingException weirdKeyException(Class<?> keyClass, String keyValue
}

/**
* Helper method for constructing exception to indicate that end-of-input was
* reached while still expecting more tokens to deserialize value of specified type.
*
* @deprecated Since 2.8; currently no way to catch EOF at databind level
* Helper method for constructing exception to indicate that given JSON
* Object field name was not in format to be able to deserialize specified
* key type.
*/
@Deprecated
public JsonMappingException endOfInputException(Class<?> instClass) {
return JsonMappingException.from(_parser, "Unexpected end-of-input when trying to deserialize a "
+instClass.getName());
public JsonMappingException unknownTypeIdException(JavaType baseType, String typeId,
String extraDesc) {
String msg = String.format("Could not resolve type id '%s' into a subtype of %s",
typeId, baseType);
if (extraDesc != null) {
msg = msg + ": "+extraDesc;
}
return InvalidTypeIdException.from(_parser, msg, baseType, typeId);
}

/*
/**********************************************************
/* Methods for constructing semantic exceptions; mostly
Expand Down Expand Up @@ -1200,6 +1204,18 @@ public JsonMappingException unknownTypeException(JavaType type, String id,
return JsonMappingException.from(_parser, msg);
}

/**
* Helper method for constructing exception to indicate that end-of-input was
* reached while still expecting more tokens to deserialize value of specified type.
*
* @deprecated Since 2.8; currently no way to catch EOF at databind level
*/
@Deprecated
public JsonMappingException endOfInputException(Class<?> instClass) {
return JsonMappingException.from(_parser, "Unexpected end-of-input when trying to deserialize a "
+instClass.getName());
}

/*
/**********************************************************
/* Overridable internal methods
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.fasterxml.jackson.databind.exc;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;

/**
* Exception thrown when resolution of a type id fails.
*
* @since 2.8
*/
public class InvalidTypeIdException extends JsonMappingException
{
private static final long serialVersionUID = 1L; // silly Eclipse, warnings

/**
* Basetype for which subtype was to be resolved
*/
protected final JavaType _baseType;

/**
* Type id that failed to be resolved to a subtype
*/
protected final String _typeId;

/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/

public InvalidTypeIdException(JsonParser p, String msg,
JavaType baseType, String typeId)
{
super(p, msg);
_baseType = baseType;
_typeId = typeId;
}

public static InvalidTypeIdException from(JsonParser p, String msg,
JavaType baseType, String typeId) {
return new InvalidTypeIdException(p, msg, baseType, typeId);
}

/*
/**********************************************************
/* Accessors
/**********************************************************
*/

public JavaType getBaseType() { return _baseType; }
public String getTypeId() { return _typeId; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;

/**
* Tests to exercise handler methods of {@link DeserializationProblemHandler}.
Expand Down Expand Up @@ -66,6 +67,8 @@ static class BaseWrapper {
/**********************************************************
*/

private final ObjectMapper MAPPER = new ObjectMapper();

public void testWeirdKeyHandling() throws Exception
{
ObjectMapper mapper = new ObjectMapper()
Expand All @@ -86,4 +89,18 @@ public void testInvalidTypeId() throws Exception
BaseWrapper.class);
assertNotNull(w);
}

// verify that by default we get special exception type
public void testInvalidTypeIdFail() throws Exception
{
try {
MAPPER.readValue("{\"value\":{\"type\":\"foo\",\"a\":4}}",
BaseWrapper.class);
fail("Should not pass");
} catch (InvalidTypeIdException e) {
verifyException(e, "Could not resolve type id 'foo'");
assertEquals(Base.class, e.getBaseType().getRawClass());
assertEquals("foo", e.getTypeId());
}
}
}

0 comments on commit 1ecc6b5

Please sign in to comment.