Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Array index missing in path of JsonMappingException for Collection<String>, with custom deserializer #2473

Closed
joca-bt opened this issue Sep 24, 2019 · 2 comments

Comments

@joca-bt
Copy link

joca-bt commented Sep 24, 2019

In some situations the path of a JsonMappingException doesn't contain the array index where the error occurred.

In the following example we have a custom string deserializer which is disabling the automatic casting from other types (#796).

try {
    mapper.readValue("{ \"array\": [ \"foo\", true ]}", Foo.class);
} catch (JsonMappingException exception) {
    System.out.println(exception); // 1
    for (var node : exception.getPath()) {
        System.out.println(node); // 2
        System.out.println(node.getFieldName()); // 3
        System.out.println(node.getIndex()); // 4
    }
}

public class Foo {
    public List<String> array;
}

public class StringDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        if (parser.hasToken(JsonToken.VALUE_STRING)) {
            return parser.getText();
        } else {
            throw context.wrongTokenException(parser, String.class, JsonToken.VALUE_STRING, "");
        }
    }
}
1: com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (VALUE_TRUE), expected VALUE_STRING:
 at [Source: (String)"{ "array": [ "foo", true ]}"; line: 1, column: 21] (through reference chain: Foo["array"])
2: Foo["array"]
3: array
4: -1

In this case, there's no information about the array index in which the error is originating, since the path only has 1 node (it should have two like below).

In other situations we do, for example:

"{ \"array\": [ true, 1 ]}"

public class Foo {
    public List<Boolean> array;
}
1: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot coerce Number (1) for type `java.lang.Boolean` (enable `MapperFeature.ALLOW_COERCION_OF_SCALARS` to allow)
 at [Source: (PushbackInputStream); line: 2, column: 27] (through reference chain: Foo["array"]->java.util.ArrayList[1])
2: Foo["array"]
3: array
4: -1
2: java.util.ArrayList[1]
3: null
4: 1

Is there something different when using custom deserializers?

@cowtowncoder
Copy link
Member

No, location tracking should work the same way... but it is possible that something in deserializer for List<Object> is different from that of more specialized List<String> (internally there is optimized handler for second case).
So it sounds like a bug. Thank you for reporting this!

@cowtowncoder cowtowncoder changed the title Array index missing in path of JsonMappingException Array index missing in path of JsonMappingException for Collection<String>, with custom deserializer Sep 30, 2019
@cowtowncoder
Copy link
Member

Ok so... deserializers do need to add try-catch block to include location information, and this was missing from one code path of StringCollectionDeserializer. I added handling, but do not have a good unit test; would be nice to have, but for now location information can be seen from sample given. Fix will be in 2.10.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants