Skip to content

Commit 09ec427

Browse files
committed
Dedicated types for standard exceptions, see AsyncHttpClient#1014
1 parent a048f56 commit 09ec427

12 files changed

+148
-32
lines changed

client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*/
1414
package org.asynchttpclient.netty.channel;
1515

16-
import static org.asynchttpclient.util.MiscUtils.buildStaticIOException;
16+
import static org.asynchttpclient.util.MiscUtils.trimStackTrace;
1717
import io.netty.bootstrap.Bootstrap;
1818
import io.netty.buffer.PooledByteBufAllocator;
1919
import io.netty.channel.Channel;
@@ -53,6 +53,9 @@
5353
import org.asynchttpclient.handler.AsyncHandlerExtensions;
5454
import org.asynchttpclient.netty.Callback;
5555
import org.asynchttpclient.netty.NettyResponseFuture;
56+
import org.asynchttpclient.netty.channel.exception.PoolAlreadyClosedException;
57+
import org.asynchttpclient.netty.channel.exception.TooManyConnectionsException;
58+
import org.asynchttpclient.netty.channel.exception.TooManyConnectionsPerHostException;
5659
import org.asynchttpclient.netty.channel.pool.ChannelPool;
5760
import org.asynchttpclient.netty.channel.pool.DefaultChannelPool;
5861
import org.asynchttpclient.netty.channel.pool.NoopChannelPool;
@@ -91,7 +94,6 @@ public class ChannelManager {
9194
private final long handshakeTimeout;
9295
private final IOException tooManyConnections;
9396
private final IOException tooManyConnectionsPerHost;
94-
private final IOException poolAlreadyClosed;
9597

9698
private final ChannelPool channelPool;
9799
private final boolean maxTotalConnectionsEnabled;
@@ -123,9 +125,8 @@ public ChannelManager(final AsyncHttpClientConfig config, Timer nettyTimer) {
123125
}
124126
this.channelPool = channelPool;
125127

126-
tooManyConnections = buildStaticIOException("Too many connections " + config.getMaxConnections());
127-
tooManyConnectionsPerHost = buildStaticIOException("Too many connections per host " + config.getMaxConnectionsPerHost());
128-
poolAlreadyClosed = buildStaticIOException("Pool is already closed");
128+
tooManyConnections = trimStackTrace(new TooManyConnectionsException(config.getMaxConnections()));
129+
tooManyConnectionsPerHost = trimStackTrace(new TooManyConnectionsPerHostException(config.getMaxConnectionsPerHost()));
129130
maxTotalConnectionsEnabled = config.getMaxConnections() > 0;
130131
maxConnectionsPerHostEnabled = config.getMaxConnectionsPerHost() > 0;
131132

@@ -325,7 +326,7 @@ private boolean tryAcquirePerHost(Object partitionKey) {
325326

326327
public void preemptChannel(Object partitionKey) throws IOException {
327328
if (!channelPool.isOpen())
328-
throw poolAlreadyClosed;
329+
throw PoolAlreadyClosedException.INSTANCE;
329330
if (!tryAcquireGlobal())
330331
throw tooManyConnections;
331332
if (!tryAcquirePerHost(partitionKey)) {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2015 AsyncHttpClient Project. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
package org.asynchttpclient.netty.channel.exception;
14+
15+
import java.io.IOException;
16+
17+
import static org.asynchttpclient.util.MiscUtils.trimStackTrace;
18+
19+
@SuppressWarnings("serial")
20+
public final class ChannelClosedException extends IOException {
21+
22+
public static final ChannelClosedException INSTANCE = trimStackTrace(new ChannelClosedException());
23+
24+
private ChannelClosedException() {
25+
super("Channel closed");
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2015 AsyncHttpClient Project. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
package org.asynchttpclient.netty.channel.exception;
14+
15+
import java.io.IOException;
16+
17+
import static org.asynchttpclient.util.MiscUtils.trimStackTrace;
18+
19+
@SuppressWarnings("serial")
20+
public class PoolAlreadyClosedException extends IOException {
21+
22+
public static final PoolAlreadyClosedException INSTANCE = trimStackTrace(new PoolAlreadyClosedException());
23+
24+
private PoolAlreadyClosedException() {
25+
super("Pool is already closed");
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2015 AsyncHttpClient Project. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
package org.asynchttpclient.netty.channel.exception;
14+
15+
import java.io.IOException;
16+
17+
import static org.asynchttpclient.util.MiscUtils.trimStackTrace;
18+
19+
@SuppressWarnings("serial")
20+
public final class RemotelyClosedException extends IOException {
21+
22+
public static final RemotelyClosedException INSTANCE = trimStackTrace(new RemotelyClosedException());
23+
24+
public RemotelyClosedException() {
25+
super("Remotely closed");
26+
}
27+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2015 AsyncHttpClient Project. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
package org.asynchttpclient.netty.channel.exception;
14+
15+
import java.io.IOException;
16+
17+
@SuppressWarnings("serial")
18+
public class TooManyConnectionsException extends IOException {
19+
20+
public TooManyConnectionsException(int max) {
21+
super("Too many connections per host " + max);
22+
}
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright (c) 2015 AsyncHttpClient Project. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
7+
*
8+
* Unless required by applicable law or agreed to in writing,
9+
* software distributed under the Apache License Version 2.0 is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
12+
*/
13+
package org.asynchttpclient.netty.channel.exception;
14+
15+
import java.io.IOException;
16+
17+
@SuppressWarnings("serial")
18+
public class TooManyConnectionsPerHostException extends IOException {
19+
20+
public TooManyConnectionsPerHostException(int max) {
21+
super("Too many connections " + max);
22+
}
23+
}

client/src/main/java/org/asynchttpclient/netty/handler/AsyncHttpClientHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
*/
1414
package org.asynchttpclient.netty.handler;
1515

16-
import static org.asynchttpclient.util.HttpUtils.CHANNEL_CLOSED_EXCEPTION;
1716
import static org.asynchttpclient.util.MiscUtils.getCause;
1817
import io.netty.buffer.ByteBuf;
1918
import io.netty.channel.Channel;
@@ -35,6 +34,7 @@
3534
import org.asynchttpclient.netty.NettyResponseFuture;
3635
import org.asynchttpclient.netty.channel.ChannelManager;
3736
import org.asynchttpclient.netty.channel.Channels;
37+
import org.asynchttpclient.netty.channel.exception.ChannelClosedException;
3838
import org.asynchttpclient.netty.future.StackTraceInspector;
3939
import org.asynchttpclient.netty.request.NettyRequestSender;
4040
import org.slf4j.Logger;
@@ -148,7 +148,7 @@ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
148148
NettyResponseFuture<?> future = NettyResponseFuture.class.cast(attribute);
149149
future.touch();
150150

151-
if (!config.getIoExceptionFilters().isEmpty() && requestSender.applyIoExceptionFiltersAndReplayRequest(future, CHANNEL_CLOSED_EXCEPTION, channel))
151+
if (!config.getIoExceptionFilters().isEmpty() && requestSender.applyIoExceptionFiltersAndReplayRequest(future, ChannelClosedException.INSTANCE, channel))
152152
return;
153153

154154
protocol.onClose(future);
@@ -186,7 +186,7 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) throws Excep
186186
// FIXME why drop the original exception and throw a new
187187
// one?
188188
if (!config.getIoExceptionFilters().isEmpty()) {
189-
if (!requestSender.applyIoExceptionFiltersAndReplayRequest(future, CHANNEL_CLOSED_EXCEPTION, channel))
189+
if (!requestSender.applyIoExceptionFiltersAndReplayRequest(future, ChannelClosedException.INSTANCE, channel))
190190
// Close the channel so the recovering can occurs.
191191
Channels.silentlyCloseChannel(channel);
192192
return;

client/src/main/java/org/asynchttpclient/netty/request/NettyRequestSender.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import static org.asynchttpclient.util.Assertions.assertNotNull;
1717
import static org.asynchttpclient.util.AuthenticatorUtils.*;
18-
import static org.asynchttpclient.util.HttpUtils.*;
18+
import static org.asynchttpclient.util.HttpUtils.requestTimeout;
1919
import static org.asynchttpclient.util.MiscUtils.getCause;
2020
import static org.asynchttpclient.util.ProxyUtils.getProxyServer;
2121
import io.netty.bootstrap.Bootstrap;
@@ -52,6 +52,7 @@
5252
import org.asynchttpclient.netty.channel.ChannelState;
5353
import org.asynchttpclient.netty.channel.Channels;
5454
import org.asynchttpclient.netty.channel.NettyConnectListener;
55+
import org.asynchttpclient.netty.channel.exception.RemotelyClosedException;
5556
import org.asynchttpclient.netty.timeout.ReadTimeoutTimerTask;
5657
import org.asynchttpclient.netty.timeout.RequestTimeoutTimerTask;
5758
import org.asynchttpclient.netty.timeout.TimeoutsHolder;
@@ -389,7 +390,7 @@ public void handleUnexpectedClosedChannel(Channel channel, NettyResponseFuture<?
389390
channelManager.closeChannel(channel);
390391

391392
else if (!retry(future))
392-
abort(channel, future, REMOTELY_CLOSED_EXCEPTION);
393+
abort(channel, future, RemotelyClosedException.INSTANCE);
393394
}
394395

395396
public boolean retry(NettyResponseFuture<?> future) {

client/src/main/java/org/asynchttpclient/util/HttpUtils.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
package org.asynchttpclient.util;
1414

1515
import static java.nio.charset.StandardCharsets.ISO_8859_1;
16-
import static org.asynchttpclient.util.MiscUtils.*;
16+
import static org.asynchttpclient.util.MiscUtils.isNonEmpty;
1717

18-
import java.io.IOException;
1918
import java.nio.ByteBuffer;
2019
import java.nio.charset.Charset;
2120
import java.util.List;
@@ -30,9 +29,6 @@
3029
*/
3130
public class HttpUtils {
3231

33-
public static final IOException REMOTELY_CLOSED_EXCEPTION = buildStaticIOException("Remotely closed");
34-
public static final IOException CHANNEL_CLOSED_EXCEPTION = buildStaticIOException("Channel closed");
35-
3632
public final static Charset DEFAULT_CHARSET = ISO_8859_1;
3733

3834
public static final void validateSupportedScheme(Uri uri) {

client/src/main/java/org/asynchttpclient/util/MiscUtils.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,9 @@ public static void closeSilently(Closeable closeable) {
5959
}
6060
}
6161

62-
public static IOException buildStaticIOException(String message) {
63-
IOException ioe = new IOException(message);
64-
ioe.setStackTrace(new StackTraceElement[] {});
65-
return ioe;
62+
public static <T extends Exception> T trimStackTrace(T e) {
63+
e.setStackTrace(new StackTraceElement[] {});
64+
return e;
6665
}
6766

6867
public static Throwable getCause(Throwable t) {

client/src/test/java/org/asynchttpclient/AuthTimeoutTest.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import javax.servlet.http.HttpServletRequest;
2727
import javax.servlet.http.HttpServletResponse;
2828

29-
import org.asynchttpclient.util.HttpUtils;
29+
import org.asynchttpclient.netty.channel.exception.RemotelyClosedException;
3030
import org.eclipse.jetty.server.Request;
3131
import org.eclipse.jetty.server.Server;
3232
import org.eclipse.jetty.server.handler.AbstractHandler;
@@ -168,11 +168,7 @@ public void digestFuturePreemptiveAuthTimeoutTest() throws Exception {
168168
}
169169

170170
protected void inspectException(Throwable t) {
171-
assertNotNull(t.getCause());
172-
assertEquals(t.getCause().getClass(), IOException.class);
173-
if (t.getCause() != HttpUtils.REMOTELY_CLOSED_EXCEPTION) {
174-
fail();
175-
}
171+
assertEquals(t.getCause(), RemotelyClosedException.INSTANCE);
176172
}
177173

178174
private AsyncHttpClient newClient() {

client/src/test/java/org/asynchttpclient/RetryRequestTest.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import javax.servlet.http.HttpServletRequest;
2323
import javax.servlet.http.HttpServletResponse;
2424

25-
import org.asynchttpclient.util.HttpUtils;
25+
import org.asynchttpclient.netty.channel.exception.RemotelyClosedException;
2626
import org.eclipse.jetty.server.Request;
2727
import org.eclipse.jetty.server.handler.AbstractHandler;
2828
import org.testng.annotations.Test;
@@ -74,11 +74,7 @@ public void testMaxRetry() throws Exception {
7474
ahc.executeRequest(ahc.prepareGet(getTargetUrl()).build()).get();
7575
fail();
7676
} catch (Exception t) {
77-
assertNotNull(t.getCause());
78-
assertEquals(t.getCause().getClass(), IOException.class);
79-
if (t.getCause() != HttpUtils.REMOTELY_CLOSED_EXCEPTION) {
80-
fail();
81-
}
77+
assertEquals(t.getCause(), RemotelyClosedException.INSTANCE);
8278
}
8379
}
8480
}

0 commit comments

Comments
 (0)