I'm trying to return a custom http response(400 bad request) instead of http 500 server error when json payload is not valid.
The problem is that when I use javax.json.bind.JsonbException
as exception type in ExceptionMapper<T>
it's not able to catch it, but I can catch the more generic javax.ws.rs.ProcessingException
.
It is obvious that the javax.ws.rs.ProcessingException
is caused by javax.json.bind.JsonbException
as stack trace is showing:
javax.ws.rs.ProcessingException: Error deserializing object from entity stream.
at org.glassfish.jersey.jsonb.internal.JsonBindingProvider.readFrom(JsonBindingProvider.java:86)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:233)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:212)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:132)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:49)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:132)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1072)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:885)
at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:290)
at org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:73)
at org.glassfish.jersey.server.internal.inject.EntityParamValueParamProvider$EntityValueSupplier.apply(EntityParamValueParamProvider.java:56)
at org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.apply(ParamValueFactoryWithSource.java:50)
at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:68)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:109)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:159)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:475)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:397)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
at io.helidon.webserver.jersey.JerseySupport$JerseyHandler.lambda$doAccept$4(JerseySupport.java:326)
at io.helidon.common.context.Contexts.runInContext(Contexts.java:117)
at io.helidon.common.context.ContextAwareExecutorImpl.lambda$wrap$7(ContextAwareExecutorImpl.java:154)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: javax.json.bind.JsonbException: Unable to deserialize property 'date' because of: Error parsing class java.util.Date from value: 2022-03-31T10:37:23.005Z[UTC]x. Check your @JsonbDateFormat has all time units for class java.util.Date type, or consider using org.eclipse.yasson.YassonConfig#ZERO_TIME_PARSE_DEFAULTING.
at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserializeInternal(AbstractContainerDeserializer.java:100)
at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserialize(AbstractContainerDeserializer.java:64)
at org.eclipse.yasson.internal.Unmarshaller.deserializeItem(Unmarshaller.java:62)
at org.eclipse.yasson.internal.Unmarshaller.deserialize(Unmarshaller.java:51)
at org.eclipse.yasson.internal.JsonBinding.deserialize(JsonBinding.java:59)
at org.eclipse.yasson.internal.JsonBinding.fromJson(JsonBinding.java:99)
at org.glassfish.jersey.jsonb.internal.JsonBindingProvider.readFrom(JsonBindingProvider.java:84)
... 33 more
Caused by: javax.json.bind.JsonbException: Error parsing class java.util.Date from value: 2022-03-31T10:37:23.005Z[UTC]x. Check your @JsonbDateFormat has all time units for class java.util.Date type, or consider using org.eclipse.yasson.YassonConfig#ZERO_TIME_PARSE_DEFAULTING.
at org.eclipse.yasson.internal.serializer.AbstractDateTimeDeserializer.deserialize(AbstractDateTimeDeserializer.java:74)
at org.eclipse.yasson.internal.serializer.AbstractValueTypeDeserializer.deserialize(AbstractValueTypeDeserializer.java:64)
at org.eclipse.yasson.internal.serializer.ObjectDeserializer.deserializeNext(ObjectDeserializer.java:180)
at org.eclipse.yasson.internal.serializer.AbstractContainerDeserializer.deserializeInternal(AbstractContainerDeserializer.java:94)
... 39 more
Caused by: java.time.format.DateTimeParseException: Text '2022-03-31T10:37:23.005Z[UTC]x' could not be parsed, unparsed text found at index 29
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2055)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954)
at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:600)
at org.eclipse.yasson.internal.serializer.DateTypeDeserializer.parseWithOrWithoutZone(DateTypeDeserializer.java:79)
at org.eclipse.yasson.internal.serializer.DateTypeDeserializer.parseDefault(DateTypeDeserializer.java:49)
at org.eclipse.yasson.internal.serializer.DateTypeDeserializer.parseDefault(DateTypeDeserializer.java:29)
at org.eclipse.yasson.internal.serializer.AbstractDateTimeDeserializer.deserialize(AbstractDateTimeDeserializer.java:72)
... 42 more
But I was wondering if there is a way to catch the javax.json.bind.JsonbException
?
I am using Helidon-MP 2.4.2.
Reproduce:
- create a quick start of Helidon-MP Link
- add a post method on greeting resource
@POST
@Consumes(MediaType.APPLICATION_JSON)
public void add(MyClass cal){
System.out.println(cal.getDate());
}
public class MyClass {
private String name;
private Date date;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public MyClass(String name, Date date) {
this.name = name;
this.date = date;
}
public MyClass() {
}
}
3.send a post request with invalid json date. valid payoad:
{
"name": "testg",
"date": "2022-03-31T10:37:23.005Z[UTC]"
}
invalid (date) payload:
{
"name": "testg",
"date": "2022-03-31T10:37:23.005Z[UTC]XXXXXXXX"
}