I would like HttpClient 5 to retry requests when facing a TunnelRefusedException (it happens randomly that the proxy refuses the initial connection, but it usually works ok when retrying).
I have tried extending DefaultHttpRequestRetryStrategy but it can only capture exceptions inheriting from IOException
:
public class MyRetryStrategy extends DefaultHttpRequestRetryStrategy {
public MyRetryStrategy() {
super(2,
TimeValue.ofSeconds(1L),
Arrays.asList(InterruptedIOException.class, UnknownHostException.class, ConnectException.class, ConnectionClosedException.class, NoRouteToHostException.class, SSLException.class,
TunnelRefusedException.class // not valid, because it is not an IOException !
),
Arrays.asList(429, 503)
);
}
}
So, maybe HttpRequestRetryStrategy
interface should support any kind of Exception
? Or maybe TunnelRefusedException
should be an IOException
?
Any ideas about how to do this?
Sample stacktrace of the error that I would like to retry:
org.apache.hc.client5.http.ClientProtocolException: CONNECT refused by proxy: HTTP/1.1 500 Internal Server Error
at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:173)
at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:245)
at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:188)
[...]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: org.apache.hc.client5.http.impl.TunnelRefusedException: CONNECT refused by proxy: HTTP/1.1 500 Internal Server Error
at org.apache.hc.client5.http.impl.classic.ConnectExec.createTunnelToTarget(ConnectExec.java:284)
at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:151)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:192)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:96)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:152)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:115)
at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:170)
... 19 more
DefaultHttpRequestRetryStrategy has excluded exception list in the definition see them here
Easiest way to go is to implement custom strategy and custom exec chain handler.
My local tests output looks like below
check here for full working example project.