Ray Wu
Ray Wu

Reputation: 1033

How to customize error response when deserializing failed

I have a jaxrs endpoint service, in my own ResourceConfig I register an ExceptionMapper, so when somewhere wrong happened, it will return a JSON { errorEnum: "something" }. The service class looks like this.

@POST
@Path("/query")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response query(final QueryDefinition queryDefinition) {
    ...
}

However, in my payload, there is a field which is Enum. If any user made a typo in that field, the error message will be

Can not deserialize value of type FIELD from String "AAA": value not
one of declared Enum instance names: [AAA, BBB, CCC]  at [Source:
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@62ac814;
line: 15, column: 17] (through reference chain:
QueryDefinition["FIELD"])

I tried to use the customized EnumDeserializer,

public class EnumDeserializer extends JsonDeserializer<Enum   {
    @Override
    public Dimensions deserialize(JsonParser jp, DeserializationContext deserializationContext) throws IOException,
JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        String enumName = node.textValue();
        Enum e = Enums.fromString(enumName);
        if (e != null) { return e; }
        throw new CustomizedException("Not supported Enum");
    } }

But then the response becomes Not supported Enum (through reference chain: QueryDefinition["FIELD"]), which is still not what I want.

Upvotes: 1

Views: 1496

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 209132

The Jackson provider already has ExceptionMappers1 that will just return the exception message when an exception is caught. If you want, you can just create your own ExceptionMapper for these exceptions, i.e. JsonParseException and JsonMappingException, and just return the message you want. Then just register those mappers with the Jersey application. This should override the ones registered by Jackson.

The reason your exception mapper doesn't work is because the ones from Jackson are more specific. The more specific one always gets invoked.

1 - namely JsonParseExceptionMapper and JsonMappingExceptionMapper

Upvotes: 3

Related Questions