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

Deserialization of AbstractThrowableProblem implementation fails with InvalidTypeIdException #485

Open
FRosner opened this issue Jan 22, 2024 · 2 comments
Labels

Comments

@FRosner
Copy link

FRosner commented Jan 22, 2024

Description

I defined a custom problem ResourceNotFoundProblem and I was checking it in my unit test. However, the object mapper failed to deserialize it with the following exception:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'https://your-company.com/problems/ResourceNotFoundProblem.html as a subtype of `ResourceNotFoundProblem`: known type ids = [ResourceNotFoundProblem]
 at [Source: (String)"{"id":"cd892175-ea84-4329-a3a0-aa7c40155bda","type":"https://your-company.com/problems/ResourceNotFoundProblem.html","title":"Resource not found","status":404,"detail":"Task cd892175-ea84-4329-a3a0-aa7c40155bda not found. Did you submit it recently? It may have expired from the result cache, or you might have submitted it to a different process."}"; line: 1, column: 53]

I don't know why, because I did not provide any JsonTypeInfo property. Here's my class definition:

public final class ResourceNotFoundProblem extends AbstractThrowableProblem
{

    static final URI TYPE = URI.create(String.format("https://your-company.com/problems/%s.html", ResourceNotFoundProblem.class.getSimpleName()));

    public final String id;

    public ResourceNotFoundProblem(final String id, final String detail) {
        super(TYPE, "Resource not found", Status.NOT_FOUND, detail);
        this.id = id;
    }

}

And here's a sample to reproduce:

String ser = OBJECT_MAPPER.writeValueAsString(new ResourceNotFoundProblem("id", "detail"));
ResourceNotFoundProblem deser = OBJECT_MAPPER.readValue(ser, ResourceNotFoundProblem.class);

Here's my object mapper.

public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .configure(MapperFeature.IGNORE_DUPLICATE_MODULE_REGISTRATIONS, true)
            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
            .registerModule(new JavaTimeModule())
            .registerModule(new Jdk8Module())
            .registerModule(new ProblemModule());

Expected Behavior

I expect the deserialization to work.

Actual Behavior

The deserialization does not work.

Possible Fix

Not sure what the root cause is. Is this expected to work?

Steps to Reproduce

String ser = OBJECT_MAPPER.writeValueAsString(new ResourceNotFoundProblem("id", "detail"));
ResourceNotFoundProblem deser = OBJECT_MAPPER.readValue(ser, ResourceNotFoundProblem.class);

Context

I can't test my code.

Your Environment

  • Problem 0.27.1
  • Jackson databind 2.14.2
@FRosner FRosner added the Bug label Jan 22, 2024
@A3Ackerman
Copy link

Bump. I am experiencing the same issue trying to deserialize a Zalando problem to extract the error details.

@whiskeysierra
Copy link
Collaborator

I believe you have to register your type (using ObjectMapper.registerSubtypes(...)) as a subtype so that Jackson knows about when when deserializing.

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

No branches or pull requests

3 participants