Remove ChannelHandler.exceptionCaught(...) as it should only exist in… (#8822)
Motivation: ChannelHandler.exceptionCaught(...) was marked as @deprecated as it should only exist in inbound handlers. Modifications: Remove ChannelHandler.exceptionCaught(...) and adjust code / tests. Result: Fixes https://github.com/netty/netty/issues/8527
This commit is contained in:
parent
9725cae033
commit
e3846c54f6
@ -20,7 +20,6 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerAdapter;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
@ -43,7 +42,6 @@ import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpObject;
|
||||
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||
import io.netty.handler.codec.http.HttpVersion;
|
||||
import io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable;
|
||||
import io.netty.util.AsciiString;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.util.concurrent.Future;
|
||||
@ -667,7 +665,7 @@ public class InboundHttp2ToHttpAdapterTest {
|
||||
|
||||
clientDelegator = new HttpResponseDelegator(clientListener, clientLatch, clientLatch2);
|
||||
p.addLast(clientDelegator);
|
||||
p.addLast(new ChannelHandlerAdapter() {
|
||||
p.addLast(new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
Http2Exception e = getEmbeddedHttp2Exception(cause);
|
||||
|
@ -136,11 +136,6 @@ public class DatagramPacketEncoder<M> extends MessageToMessageEncoder<AddressedE
|
||||
encoder.handlerRemoved(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
encoder.exceptionCaught(ctx, cause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSharable() {
|
||||
return encoder.isSharable();
|
||||
|
@ -19,6 +19,7 @@ import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelProgressivePromise;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
@ -107,12 +108,15 @@ public abstract class EmbeddedChannelHandlerContext implements ChannelHandlerCon
|
||||
|
||||
@Override
|
||||
public final ChannelHandlerContext fireExceptionCaught(Throwable cause) {
|
||||
ChannelHandler handler = handler();
|
||||
try {
|
||||
handler().exceptionCaught(this, cause);
|
||||
if (handler instanceof ChannelInboundHandler) {
|
||||
((ChannelInboundHandler) handler).exceptionCaught(this, cause);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
handleException(e);
|
||||
}
|
||||
return null;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -188,14 +188,6 @@ public interface ChannelHandler {
|
||||
*/
|
||||
void handlerRemoved(ChannelHandlerContext ctx) throws Exception;
|
||||
|
||||
/**
|
||||
* Gets called if a {@link Throwable} was thrown.
|
||||
*
|
||||
* @deprecated is part of {@link ChannelInboundHandler}
|
||||
*/
|
||||
@Deprecated
|
||||
void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
|
||||
|
||||
/**
|
||||
* Indicates that the same instance of the annotated {@link ChannelHandler}
|
||||
* can be added to one or more {@link ChannelPipeline}s multiple times
|
||||
|
@ -80,16 +80,4 @@ public abstract class ChannelHandlerAdapter implements ChannelHandler {
|
||||
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link ChannelHandlerContext#fireExceptionCaught(Throwable)} to forward
|
||||
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
|
||||
*
|
||||
* Sub-classes may override this method to change behavior.
|
||||
*/
|
||||
@Skip
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
ctx.fireExceptionCaught(cause);
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,5 @@ public interface ChannelInboundHandler extends ChannelHandler {
|
||||
/**
|
||||
* Gets called if a {@link Throwable} was thrown.
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
|
||||
}
|
||||
|
@ -19,9 +19,6 @@ import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.util.Attribute;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.concurrent.EventExecutor;
|
||||
import io.netty.util.internal.ThrowableUtil;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
|
||||
@ -31,8 +28,6 @@ import java.net.SocketAddress;
|
||||
public class CombinedChannelDuplexHandler<I extends ChannelInboundHandler, O extends ChannelOutboundHandler>
|
||||
extends ChannelDuplexHandler {
|
||||
|
||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(CombinedChannelDuplexHandler.class);
|
||||
|
||||
private DelegatingChannelHandlerContext inboundCtx;
|
||||
private DelegatingChannelHandlerContext outboundCtx;
|
||||
private volatile boolean handlerAdded;
|
||||
@ -136,35 +131,7 @@ public class CombinedChannelDuplexHandler<I extends ChannelInboundHandler, O ext
|
||||
}
|
||||
|
||||
outboundCtx = new DelegatingChannelHandlerContext(ctx, outboundHandler);
|
||||
inboundCtx = new DelegatingChannelHandlerContext(ctx, inboundHandler) {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public ChannelHandlerContext fireExceptionCaught(Throwable cause) {
|
||||
if (!outboundCtx.removed) {
|
||||
try {
|
||||
// We directly delegate to the ChannelOutboundHandler as this may override exceptionCaught(...)
|
||||
// as well
|
||||
outboundHandler.exceptionCaught(outboundCtx, cause);
|
||||
} catch (Throwable error) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"An exception {}" +
|
||||
"was thrown by a user handler's exceptionCaught() " +
|
||||
"method while handling the following exception:",
|
||||
ThrowableUtil.stackTraceToString(error), cause);
|
||||
} else if (logger.isWarnEnabled()) {
|
||||
logger.warn(
|
||||
"An exception '{}' [enable DEBUG level for full stacktrace] " +
|
||||
"was thrown by a user handler's exceptionCaught() " +
|
||||
"method while handling the following exception:", error, cause);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
super.fireExceptionCaught(cause);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
};
|
||||
inboundCtx = new DelegatingChannelHandlerContext(ctx, inboundHandler);
|
||||
|
||||
// The inboundCtx and outboundCtx were created and set now it's safe to call removeInboundHandler() and
|
||||
// removeOutboundHandler().
|
||||
@ -371,7 +338,7 @@ public class CombinedChannelDuplexHandler<I extends ChannelInboundHandler, O ext
|
||||
}
|
||||
}
|
||||
|
||||
private static class DelegatingChannelHandlerContext implements ChannelHandlerContext {
|
||||
private static final class DelegatingChannelHandlerContext implements ChannelHandlerContext {
|
||||
|
||||
private final ChannelHandlerContext ctx;
|
||||
private final ChannelHandler handler;
|
||||
@ -609,7 +576,7 @@ public class CombinedChannelDuplexHandler<I extends ChannelInboundHandler, O ext
|
||||
return ctx.channel().hasAttr(key);
|
||||
}
|
||||
|
||||
final void remove() {
|
||||
void remove() {
|
||||
EventExecutor executor = executor();
|
||||
if (executor.inEventLoop()) {
|
||||
remove0();
|
||||
|
@ -82,7 +82,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap
|
||||
private static final int MASK_WRITE = 1 << 16;
|
||||
private static final int MASK_FLUSH = 1 << 17;
|
||||
|
||||
private static final int MASK_ALL_INBOUND = MASK_CHANNEL_REGISTERED |
|
||||
private static final int MASK_ALL_INBOUND = MASK_EXCEPTION_CAUGHT | MASK_CHANNEL_REGISTERED |
|
||||
MASK_CHANNEL_UNREGISTERED | MASK_CHANNEL_ACTIVE | MASK_CHANNEL_INACTIVE | MASK_CHANNEL_READ |
|
||||
MASK_CHANNEL_READ_COMPLETE | MASK_USER_EVENT_TRIGGERED | MASK_CHANNEL_WRITABILITY_CHANGED;
|
||||
private static final int MASK_ALL_OUTBOUND = MASK_BIND | MASK_CONNECT | MASK_DISCONNECT |
|
||||
@ -154,15 +154,15 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap
|
||||
* Calculate the {@code executionMask}.
|
||||
*/
|
||||
private static int mask0(Class<? extends ChannelHandler> handlerType) {
|
||||
int mask = MASK_EXCEPTION_CAUGHT;
|
||||
int mask = 0;
|
||||
try {
|
||||
if (isSkippable(handlerType, "exceptionCaught", ChannelHandlerContext.class, Throwable.class)) {
|
||||
mask &= ~MASK_EXCEPTION_CAUGHT;
|
||||
}
|
||||
|
||||
if (ChannelInboundHandler.class.isAssignableFrom(handlerType)) {
|
||||
mask |= MASK_ALL_INBOUND;
|
||||
|
||||
if (isSkippable(handlerType, "exceptionCaught", ChannelHandlerContext.class, Throwable.class)) {
|
||||
mask &= ~MASK_EXCEPTION_CAUGHT;
|
||||
}
|
||||
|
||||
if (isSkippable(handlerType, "channelRegistered", ChannelHandlerContext.class)) {
|
||||
mask &= ~MASK_CHANNEL_REGISTERED;
|
||||
}
|
||||
@ -375,7 +375,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap
|
||||
|
||||
void invokeExceptionCaught(final Throwable cause) {
|
||||
try {
|
||||
handler().exceptionCaught(this, cause);
|
||||
((ChannelInboundHandler) handler()).exceptionCaught(this, cause);
|
||||
} catch (Throwable error) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
@ -744,7 +744,15 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap
|
||||
try {
|
||||
((ChannelOutboundHandler) handler()).read(this);
|
||||
} catch (Throwable t) {
|
||||
invokeExceptionCaughtFromOutbound(t);
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeExceptionCaughtFromOutbound(Throwable t) {
|
||||
if ((executionMask & MASK_EXCEPTION_CAUGHT) != 0) {
|
||||
notifyHandlerException(t);
|
||||
} else {
|
||||
findContextInbound(MASK_EXCEPTION_CAUGHT).notifyHandlerException(t);
|
||||
}
|
||||
}
|
||||
|
||||
@ -790,7 +798,7 @@ final class DefaultChannelHandlerContext extends DefaultAttributeMap
|
||||
try {
|
||||
((ChannelOutboundHandler) handler()).flush(this);
|
||||
} catch (Throwable t) {
|
||||
notifyHandlerException(t);
|
||||
invokeExceptionCaughtFromOutbound(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1019,7 +1019,7 @@ public class DefaultChannelPipeline implements ChannelPipeline {
|
||||
|
||||
/**
|
||||
* Called once a {@link Throwable} hit the end of the {@link ChannelPipeline} without been handled by the user
|
||||
* in {@link ChannelHandler#exceptionCaught(ChannelHandlerContext, Throwable)}.
|
||||
* in {@link ChannelInboundHandler#exceptionCaught(ChannelHandlerContext, Throwable)}.
|
||||
*/
|
||||
protected void onUnhandledInboundException(Throwable cause) {
|
||||
try {
|
||||
|
@ -89,7 +89,7 @@ public class CombinedChannelDuplexHandlerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionCaughtBothCombinedHandlers() {
|
||||
public void testExceptionCaught() {
|
||||
final Exception exception = new Exception();
|
||||
final Queue<ChannelHandler> queue = new ArrayDeque<>();
|
||||
|
||||
@ -101,14 +101,6 @@ public class CombinedChannelDuplexHandlerTest {
|
||||
ctx.fireExceptionCaught(cause);
|
||||
}
|
||||
};
|
||||
ChannelOutboundHandler outboundHandler = new ChannelOutboundHandlerAdapter() {
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
assertSame(exception, cause);
|
||||
queue.add(this);
|
||||
ctx.fireExceptionCaught(cause);
|
||||
}
|
||||
};
|
||||
ChannelInboundHandler lastHandler = new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
@ -118,11 +110,10 @@ public class CombinedChannelDuplexHandlerTest {
|
||||
};
|
||||
EmbeddedChannel channel = new EmbeddedChannel(
|
||||
new CombinedChannelDuplexHandler<>(
|
||||
inboundHandler, outboundHandler), lastHandler);
|
||||
inboundHandler, new ChannelOutboundHandlerAdapter()), lastHandler);
|
||||
channel.pipeline().fireExceptionCaught(exception);
|
||||
assertFalse(channel.finish());
|
||||
assertSame(inboundHandler, queue.poll());
|
||||
assertSame(outboundHandler, queue.poll());
|
||||
assertSame(lastHandler, queue.poll());
|
||||
assertTrue(queue.isEmpty());
|
||||
}
|
||||
|
@ -1488,7 +1488,7 @@ public class DefaultChannelPipelineTest {
|
||||
fail("handler was not one of the expected handlers");
|
||||
}
|
||||
|
||||
private static final class CheckOrderHandler extends ChannelHandlerAdapter {
|
||||
private static final class CheckOrderHandler extends ChannelInboundHandlerAdapter {
|
||||
private final Queue<CheckOrderHandler> addedQueue;
|
||||
private final Queue<CheckOrderHandler> removedQueue;
|
||||
private final AtomicReference<Throwable> error = new AtomicReference<>();
|
||||
|
@ -258,8 +258,9 @@ public class ReentrantChannelTest extends BaseChannelTest {
|
||||
throw new Exception("intentional failure");
|
||||
}
|
||||
|
||||
}, new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
ctx.close();
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user