You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
2022-11-14 20:15:06,889 WARN [] i.n.c.DefaultChannelPipeline : An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.channel.ChannelPipelineException: org.asynchttpclient.netty.handler.StreamedResponsePublisher.handlerRemoved() has thrown an exception.
at io.netty.channel.DefaultChannelPipeline.callHandlerRemoved0(DefaultChannelPipeline.java:640)
at io.netty.channel.DefaultChannelPipeline.remove(DefaultChannelPipeline.java:477)
at io.netty.channel.DefaultChannelPipeline.remove(DefaultChannelPipeline.java:417)
at org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelRead(AsyncHttpClientHandler.java:94)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1372)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1235)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1284)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:510)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:449)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:279)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800)
at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:480)
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.NullPointerException: null
That doesn't include the original NPE's stacktrace unfortunately, but looking at the implementation of HandlerPublisher.complete(), the only line that can NPE is is the call to subscriber.onComplete(); (since buffer can never be null). The minimal solution is to add a null check around the call to subscriber.onComplete();.
I mistakenly commented on #30 thinking that it was the same exception, but had misread the stacktrace the first time through. My quick diagnosis was also flawed. Looking more deeply, I think the root of the bug is a race where onComplete() is called in between where provideChannelContext() sets state to IDLE and when subscriber.onSubscribe() gets around to setting the subscriber. That's the only window in which state could be DEMANDING or IDLE and subscriber could be null that I can see. There's not a simple fix to that race, so I think the null check in onComplete is probably the best solution for now.
The text was updated successfully, but these errors were encountered:
dgolombek
pushed a commit
to dgolombek/netty-reactive-streams
that referenced
this issue
Nov 17, 2022
As described in playframework#164, I see a NPE in complete() that I believe is
caused by a race here onComplete() is called in between where
provideChannelContext() sets state to IDLE and when
subscriber.onSubscribe() gets around to setting the subscriber. A full
fix to that race is tricky, but this null check is safe. That race
could leave the publisher in a bad state, but since the handler has
been removed by that point, it shouldn't matter.
fixesplayframework#164
From a project using nett-reactive-streams 2.0.4 (via https://github.com/AsyncHttpClient/async-http-client, whose StreamedResponsePublisher extends HandlerPublisher), I see the following exception:
That doesn't include the original NPE's stacktrace unfortunately, but looking at the implementation of HandlerPublisher.complete(), the only line that can NPE is is the call to
subscriber.onComplete();
(since buffer can never be null). The minimal solution is to add a null check around the call tosubscriber.onComplete();
.I mistakenly commented on #30 thinking that it was the same exception, but had misread the stacktrace the first time through. My quick diagnosis was also flawed. Looking more deeply, I think the root of the bug is a race where onComplete() is called in between where provideChannelContext() sets state to IDLE and when subscriber.onSubscribe() gets around to setting the subscriber. That's the only window in which state could be DEMANDING or IDLE and subscriber could be null that I can see. There's not a simple fix to that race, so I think the null check in onComplete is probably the best solution for now.
The text was updated successfully, but these errors were encountered: