Closed tmapes closed 4 months ago
Can you try with 4.5.1? There was a related fix recently, not sure if it helps https://github.com/micronaut-projects/micronaut-core/pull/10953
@yawkat After some trial and error I was able to bump my local versions to the snapshots that include that PR but it didn't fix it.
After walking the call chain the RouteExecutor seems to think the return type despite explicitly being Unit
in the controller, the isKotlinFunctionReturnTypeUnit
value is being set to false.
Seems to come from this instanceof
check, it's returning false.
It's then causing the check here to become truthy, thus causing the body to be set to Unit
seems a core bug
Noted, I'll move to core.
Expected Behavior
If an
@Controller
function is bothsuspend
-able and returnsUnit
i would expect no body to be written to the caller.Actual Behaviour
Default behavior seems to be to throw a serialization exception, however various
@SerdeImport
combinations appear to sometimes serializeUnit
as an empty object ({}
).Attached repo is the former.
If a controller function returns Unit but isn't
suspend
-able it works without issue, no body is returned and no exception is thrown.Stack Trace
18:21:31.401 [kotlinx.coroutines.DefaultExecutor] ERROR i.m.http.server.RouteExecutor - Unexpected error occurred: Error encoding object [kotlin.Unit] to JSON: No serializable introspection present for type Unit. Consider adding Serdeable. Serializable annotate to type Unit. Alternatively if you are not in control of the project's source code, you can use @SerdeImport(Unit.class) to enable serialization of this type. io.micronaut.http.codec.CodecException: Error encoding object [kotlin.Unit] to JSON: No serializable introspection present for type Unit. Consider adding Serdeable. Serializable annotate to type Unit. Alternatively if you are not in control of the project's source code, you can use @SerdeImport(Unit.class) to enable serialization of this type. at io.micronaut.http.netty.body.NettyJsonHandler.writeTo(NettyJsonHandler.java:166) at io.micronaut.http.server.netty.RoutingInBoundHandler.writeNettyMessageBody(RoutingInBoundHandler.java:380) at io.micronaut.http.server.netty.RoutingInBoundHandler.encodeHttpResponse(RoutingInBoundHandler.java:358) at io.micronaut.http.server.netty.RoutingInBoundHandler.writeResponse(RoutingInBoundHandler.java:248) at io.micronaut.http.server.netty.NettyRequestLifecycle.lambda$handleNormal$0(NettyRequestLifecycle.java:101) at io.micronaut.http.reactive.execution.ReactorExecutionFlowImpl$1.onComplete(ReactorExecutionFlowImpl.java:121) at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2231) at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:159) at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74) at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:158) at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.apply(MonoCompletionStage.java:121) at reactor.core.publisher.MonoCompletionStage$MonoCompletionStageSubscription.apply(MonoCompletionStage.java:67) at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934) at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911) at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179) at io.micronaut.http.bind.binders.CustomContinuation.resumeWith(ContinuationArgumentBinder.kt:120) at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:175) at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:164) at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:466) at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:500) at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:489) at kotlinx.coroutines.CancellableContinuationImpl.resumeUndispatched(CancellableContinuationImpl.kt:587) at kotlinx.coroutines.EventLoopImplBase$DelayedResumeTask.run(EventLoop.common.kt:490) at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:277) at kotlinx.coroutines.DefaultExecutor.run(DefaultExecutor.kt:105) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: io.micronaut.serde.exceptions.SerdeException: No serializable introspection present for type Unit. Consider adding Serdeable. Serializable annotate to type Unit. Alternatively if you are not in control of the project's source code, you can use @SerdeImport(Unit.class) to enable serialization of this type. at io.micronaut.serde.support.serializers.RuntimeTypeSerializer.lambda$getSerializer$0(RuntimeTypeSerializer.java:135) at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) at io.micronaut.serde.support.serializers.RuntimeTypeSerializer.getSerializer(RuntimeTypeSerializer.java:131) at io.micronaut.serde.support.serializers.RuntimeTypeSerializer.serialize(RuntimeTypeSerializer.java:76) at io.micronaut.serde.jackson.JacksonJsonMapper.writeValue(JacksonJsonMapper.java:187) at io.micronaut.serde.jackson.JacksonJsonMapper.writeValue0(JacksonJsonMapper.java:178) at io.micronaut.serde.jackson.JacksonJsonMapper.writeValue0(JacksonJsonMapper.java:173) at io.micronaut.serde.jackson.JacksonJsonMapper.writeValue(JacksonJsonMapper.java:259) at io.micronaut.http.netty.body.NettyJsonHandler.writeTo(NettyJsonHandler.java:163) ... 27 common frames omitted Caused by: io.micronaut.core.beans.exceptions.IntrospectionException: No serializable introspection present for type Unit. Consider adding Serdeable. Serializable annotate to type Unit. Alternatively if you are not in control of the project's source code, you can use @SerdeImport(Unit.class) to enable serialization of this type. at io.micronaut.serde.support.DefaultSerdeIntrospections.getSerializableIntrospection(DefaultSerdeIntrospections.java:111) at io.micronaut.serde.support.serializers.SerBean.Steps To Reproduce
Environment Information
Example Application
https://github.com/tmapes/mn-serde-unit
Version
4.5.0