Source:
public void testExceptionDuringConnect() throws Exception { EventLoopGroup group = new DefaultEventLoopGroup(1); final LocalAddress addr = new LocalAddress("a"); final HttpHeaders headers = new DefaultHttpHeaders(); final DefaultFullHttpResponse response = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_GATEWAY); response.headers().add("name", "value"); response.headers().add(HttpHeaderNames.CONTENT_LENGTH, "0"); final AtomicReference<Throwable> exception = new AtomicReference<Throwable>(); ChannelFuture sf = new ServerBootstrap().channel(LocalServerChannel.class).group(group).childHandler( new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) { ch.pipeline().addFirst(null, new HttpResponseEncoder()); ch.writeAndFlush(response); } }).bind(addr); new Bootstrap().channel(LocalChannel.class).group(group).handler( new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) { ch.pipeline().addFirst(null, new HttpProxyHandler(addr)); ch.pipeline().addLast(new ChannelHandlerAdapter() { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { exception.set(cause); } }); } }).connect(new InetSocketAddress("localhost", 1234)).sync().channel().close().sync(); sf.channel().close().sync(); group.shutdownGracefully(); assertTrue(exception.get() instanceof HttpProxyConnectException); HttpProxyConnectException actual = (HttpProxyConnectException) exception.get(); assertNotNull(actual.headers()); assertEquals("value", actual.headers().get("name")); }

Target:
public void testExceptionDuringConnect() throws Exception { EventLoopGroup group = null; Channel serverChannel = null; Channel clientChannel = null; try { group = new DefaultEventLoopGroup(1); final LocalAddress addr = new LocalAddress("a"); final AtomicReference<Throwable> exception = new AtomicReference<Throwable>(); ChannelFuture sf = new ServerBootstrap().channel(LocalServerChannel.class).group(group).childHandler( new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) { ch.pipeline().addFirst(new HttpResponseEncoder()); DefaultFullHttpResponse response = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_GATEWAY); response.headers().add("name", "value"); response.headers().add(HttpHeaderNames.CONTENT_LENGTH, "0"); ch.writeAndFlush(response); } }).bind(addr); serverChannel = sf.sync().channel(); ChannelFuture cf = new Bootstrap().channel(LocalChannel.class).group(group).handler( new ChannelInitializer<Channel>() { @Override protected void initChannel(Channel ch) { ch.pipeline().addFirst(new HttpProxyHandler(addr)); ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { exception.set(cause); } }); } }).connect(new InetSocketAddress("localhost", 1234)); clientChannel = cf.sync().channel(); clientChannel.close().sync(); assertTrue(exception.get() instanceof HttpProxyConnectException); HttpProxyConnectException actual = (HttpProxyConnectException) exception.get(); assertNotNull(actual.headers()); assertEquals("value", actual.headers().get("name")); } finally { if (clientChannel != null) { clientChannel.close(); } if (serverChannel != null) { serverChannel.close(); } if (group != null) { group.shutdownGracefully(); } } }