I am in the process of writing a spring-integration flow that is intended to enrich the headers of a message based on the determination if a remote resource actually exists.
Assuming that there is a RESTful endpoint that has an API on it that will locate an object based on a unique name: /mix-entity/name/{mixEntityName}
.
This API will return a JSON representation of a MixEntity { "id": 1, "name": "One" }
.
In the case that a MixEntity is not found, the result will be an HTTP/404.
The HTTP/200 resultant case works fine with this, the 404 case however is where I’m struggling. I am attempting to deal with the case in a graceful fashion.
My integration flow looks roughly like the following:
@Bean public IntegrationFlow getMixEntryFlowReactive() { final WebClient webClient = webClientBuilder.defaultHeaders( headers -> headers.setBasicAuth("api", "s3cr3t") ) .build(); return f-> f.enrich( e -> e.requestSubFlow( sf -> sf.handle( WebFlux.outboundGateway("http://localhost:8080/mix-entry/name/{mixEntryName}", webClient) .httpMethod(HttpMethod.GET) .uriVariable("mixEntryName", "payload") .expectedResponseType(String.class) ) ) .headerExpression("mix-entry-id", "#jsonPath(payload, '$.id')") ) .logAndReply(); }
When I execute this with a name that does not match up, I would expect an HTTP/404, what I’m getting doesn’t make sense:
java.lang.IllegalStateException: Failed to execute CommandLineRunner at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:794) ~[spring-boot-2.5.2.jar:2.5.2] at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:775) ~[spring-boot-2.5.2.jar:2.5.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:345) ~[spring-boot-2.5.2.jar:2.5.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.2.jar:2.5.2] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.2.jar:2.5.2] at com.oneangrybean.proto.mixintegration.MixIntegrationApplication.main(MixIntegrationApplication.java:20) ~[main/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.5.2.jar:2.5.2] Caused by: org.springframework.messaging.MessageHandlingException: nested exception is org.springframework.messaging.MessageHandlingException: nested exception is java.lang.IndexOutOfBoundsException: writerIndex(1671) + minWritableBytes(6521) exceeds maxCapacity(1671): PooledSlicedByteBuf(ridx: 0, widx: 1671, cap: 1671/1671, unwrapped: PooledUnsafeDirectByteBuf(ridx: 2048, widx: 2048, cap: 2048)), failedMessage=GenericMessage [payload=Two, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@84c674d, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@84c674d, id=1d634066-6d41-961a-9909-e6b23200b8b7, timestamp=1627760756046}] at org.springframework.integration.gateway.MessagingGatewaySupport.handleSendAndReceiveError(MessagingGatewaySupport.java:577) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:546) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceiveMessage(MessagingGatewaySupport.java:491) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.transformer.ContentEnricher$Gateway.sendAndReceiveMessage(ContentEnricher.java:497) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.transformer.ContentEnricher.handleRequestMessage(ContentEnricher.java:350) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:134) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:56) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:317) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:272) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187) ~[spring-messaging-5.3.8.jar:5.3.8] at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:233) ~[spring-messaging-5.3.8.jar:5.3.8] at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:47) ~[spring-messaging-5.3.8.jar:5.3.8] at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:46) ~[spring-messaging-5.3.8.jar:5.3.8] at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:97) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:38) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.messaging.core.AbstractMessagingTemplate.convertSendAndReceive(AbstractMessagingTemplate.java:96) ~[spring-messaging-5.3.8.jar:5.3.8] at org.springframework.messaging.core.AbstractMessagingTemplate.convertSendAndReceive(AbstractMessagingTemplate.java:70) ~[spring-messaging-5.3.8.jar:5.3.8] at org.springframework.messaging.core.AbstractMessagingTemplate.convertSendAndReceive(AbstractMessagingTemplate.java:62) ~[spring-messaging-5.3.8.jar:5.3.8] at org.springframework.messaging.core.AbstractDestinationResolvingMessagingTemplate.convertSendAndReceive(AbstractDestinationResolvingMessagingTemplate.java:129) ~[spring-messaging-5.3.8.jar:5.3.8] at com.oneangrybean.proto.mixintegration.MixIntegrationApplication.lambda$4(MixIntegrationApplication.java:71) ~[main/:na] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:791) ~[spring-boot-2.5.2.jar:2.5.2] ... 10 common frames omitted Caused by: org.springframework.messaging.MessageHandlingException: nested exception is java.lang.IndexOutOfBoundsException: writerIndex(1671) + minWritableBytes(6521) exceeds maxCapacity(1671): PooledSlicedByteBuf(ridx: 0, widx: 1671, cap: 1671/1671, unwrapped: PooledUnsafeDirectByteBuf(ridx: 2048, widx: 2048, cap: 2048)) at org.springframework.integration.handler.AbstractMessageProducingHandler.sendErrorMessage(AbstractMessageProducingHandler.java:485) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.integration.handler.AbstractMessageProducingHandler$ReplyFutureCallback.onFailure(AbstractMessageProducingHandler.java:552) ~[spring-integration-core-5.5.1.jar:5.5.1] at org.springframework.util.concurrent.ListenableFutureCallbackRegistry.notifyFailure(ListenableFutureCallbackRegistry.java:86) ~[spring-core-5.3.8.jar:5.3.8] at org.springframework.util.concurrent.ListenableFutureCallbackRegistry.failure(ListenableFutureCallbackRegistry.java:158) ~[spring-core-5.3.8.jar:5.3.8] at org.springframework.util.concurrent.ListenableFutureTask.done(ListenableFutureTask.java:100) ~[spring-core-5.3.8.jar:5.3.8] at org.springframework.util.concurrent.SettableListenableFuture$SettableTask.done(SettableListenableFuture.java:175) ~[spring-core-5.3.8.jar:5.3.8] at java.base/java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:381) ~[na:na] at java.base/java.util.concurrent.FutureTask.setException(FutureTask.java:250) ~[na:na] at org.springframework.util.concurrent.SettableListenableFuture$SettableTask.setExceptionResult(SettableListenableFuture.java:163) ~[spring-core-5.3.8.jar:5.3.8] at org.springframework.util.concurrent.SettableListenableFuture.setException(SettableListenableFuture.java:70) ~[spring-core-5.3.8.jar:5.3.8] at reactor.core.publisher.LambdaMonoSubscriber.doError(LambdaMonoSubscriber.java:155) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.LambdaMonoSubscriber.onError(LambdaMonoSubscriber.java:150) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:140) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:140) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:192) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoFlatMap$FlatMapInner.onError(MonoFlatMap.java:259) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:140) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoCollectList$MonoCollectListSubscriber.onError(MonoCollectList.java:113) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onError(Operators.java:2062) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:392) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:106) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onError(MonoIgnoreThen.java:270) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:227) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2057) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.Operators.complete(Operators.java:136) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:45) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.Mono.subscribe(Mono.java:4150) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onError(MonoIgnoreElements.java:83) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:140) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onError(FluxOnAssembly.java:392) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:132) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:221) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:132) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.Operators.error(Operators.java:197) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.netty.channel.FluxReceive.startReceiver(FluxReceive.java:183) ~[reactor-netty-core-1.0.8.jar:1.0.8] at reactor.netty.channel.FluxReceive.subscribe(FluxReceive.java:144) ~[reactor-netty-core-1.0.8.jar:1.0.8] at reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:62) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.netty.ByteBufFlux.subscribe(ByteBufFlux.java:340) ~[reactor-netty-core-1.0.8.jar:1.0.8] at reactor.core.publisher.Mono.subscribe(Mono.java:4150) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:255) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.Mono.subscribe(Mono.java:4150) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:132) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.Operators$MonoSubscriber.onError(Operators.java:1862) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:140) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.MonoReduce$ReduceSubscriber.onNext(MonoReduce.java:110) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:387) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:120) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:120) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.netty.channel.FluxReceive.onInboundNext(FluxReceive.java:365) ~[reactor-netty-core-1.0.8.jar:1.0.8] at reactor.netty.channel.ChannelOperations.onInboundNext(ChannelOperations.java:405) ~[reactor-netty-core-1.0.8.jar:1.0.8] at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:707) ~[reactor-netty-http-1.0.8.jar:1.0.8] at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:94) ~[reactor-netty-core-1.0.8.jar:1.0.8] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:311) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:432) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.65.Final.jar:4.1.65.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.65.Final.jar:4.1.65.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.65.Final.jar:4.1.65.Final] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na] Caused by: java.lang.IndexOutOfBoundsException: writerIndex(1671) + minWritableBytes(6521) exceeds maxCapacity(1671): PooledSlicedByteBuf(ridx: 0, widx: 1671, cap: 1671/1671, unwrapped: PooledUnsafeDirectByteBuf(ridx: 2048, widx: 2048, cap: 2048)) at io.netty.buffer.AbstractByteBuf.ensureWritable0(AbstractByteBuf.java:294) ~[netty-buffer-4.1.65.Final.jar:4.1.65.Final] Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: Error has been observed at the following site(s): |_ checkpoint ⇢ 404 from GET http://localhost:8080/mix-entry/name/Two [DefaultWebClient] Stack trace: at io.netty.buffer.AbstractByteBuf.ensureWritable0(AbstractByteBuf.java:294) ~[netty-buffer-4.1.65.Final.jar:4.1.65.Final] at io.netty.buffer.AbstractByteBuf.ensureWritable(AbstractByteBuf.java:280) ~[netty-buffer-4.1.65.Final.jar:4.1.65.Final] at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1103) ~[netty-buffer-4.1.65.Final.jar:4.1.65.Final] at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1096) ~[netty-buffer-4.1.65.Final.jar:4.1.65.Final] at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1087) ~[netty-buffer-4.1.65.Final.jar:4.1.65.Final] at org.springframework.core.io.buffer.NettyDataBuffer.write(NettyDataBuffer.java:237) ~[spring-core-5.3.8.jar:5.3.8] at org.springframework.core.io.buffer.NettyDataBuffer.write(NettyDataBuffer.java:195) ~[spring-core-5.3.8.jar:5.3.8] at org.springframework.core.io.buffer.NettyDataBuffer.write(NettyDataBuffer.java:43) ~[spring-core-5.3.8.jar:5.3.8] at org.springframework.integration.webflux.outbound.WebFluxRequestExecutingMessageHandler.lambda$exchangeForResponseMono$4(WebFluxRequestExecutingMessageHandler.java:305) ~[spring-integration-webflux-5.5.1.jar:5.5.1] at reactor.core.publisher.MonoReduce$ReduceSubscriber.onNext(MonoReduce.java:101) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:120) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:120) ~[reactor-core-3.4.7.jar:3.4.7] at reactor.netty.channel.FluxReceive.onInboundNext(FluxReceive.java:365) ~[reactor-netty-core-1.0.8.jar:1.0.8] at reactor.netty.channel.ChannelOperations.onInboundNext(ChannelOperations.java:405) ~[reactor-netty-core-1.0.8.jar:1.0.8] at reactor.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:707) ~[reactor-netty-http-1.0.8.jar:1.0.8] at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:94) ~[reactor-netty-core-1.0.8.jar:1.0.8] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:311) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:432) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-codec-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.65.Final.jar:4.1.65.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.65.Final.jar:4.1.65.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.65.Final.jar:4.1.65.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.65.Final.jar:4.1.65.Final] at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
I see the HTTP/404 checkpoint, but it looks like the code is failing to write the response content of the HTTP/404 because it is exceeding a buffer.
I brought this up on the gitter site – Artem Bilan indicated that this might be an issue with Netty not so much Spring-Integration.
My intent here is to get to a point where if there is an HTTP/404, I can gracefully handle that and return a default response document { "id": -1, "name": null }
.
Any thoughts on this would be greatly appreciated.
OP NOTE: This change was integrated with Spring Integration releases 5.3.9.RELEASE
, 5.4.10
, and 5.5.3
.
Advertisement
Answer
@artem-bilan Helped to identify this issue. This has been addressed with spring-integration#3610