Jaikiran, Apologies for the delay, I missed this email in my inbox.
> On 12 Jun 2018, at 01:47, Jaikiran Pai <jai.forums2...@gmail.com> wrote: > > Any thoughts? > I filed the following JIRA to track this issue: https://bugs.openjdk.java.net/browse/JDK-8204864 I think that the most appropriate course of action is to consistently throw the IOException subtype, ConnectionException ( with the original cause ), for any failures encountered during a connect operation. Rather than trying to deal with the low-level NIO exceptions. I’ll resolve this issue in the sandbox, and it will likely make the next refresh [1], along with all other comments and feedback that we’ve received to date. -Chris. [1] https://bugs.openjdk.java.net/browse/JDK-8204863 > -Jaikiran > > On Sunday, June 3, 2018, Jaikiran Pai <jai.forums2...@gmail.com> wrote: > > Consider the following code: > > > > public class HttpClientTest { > > public static void main(final String[] args) { > > final HttpClient httpClient = HttpClient.newBuilder().build(); > > final String targetURL = "http://unknown.host.foo.bar.com.nowhere"; > > final HttpRequest request = > > HttpRequest.newBuilder().uri(URI.create(targetURL)) > > .method("HEAD", > > HttpRequest.BodyPublishers.noBody()) > > .build(); > > try { > > httpClient.send(request, > > HttpResponse.BodyHandlers.discarding()); > > } catch(IOException | InterruptedException e) { > > // intentionally ignore > > System.out.println("Caught an intentionally ignored exception"); > > } catch (Exception e) { > > e.printStackTrace(); > > } > > } > > } > > > > which tries to send a request to (in this case an intentional) non-existent > > address. The exception that gets thrown is: > > > > > > java.nio.channels.UnresolvedAddressException > > at java.base/sun.nio.ch.Net.checkAddress(Net.java:130) > > at > > java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:674) > > at > > java.net.http/jdk.internal.net.http.PlainHttpConnection.lambda$connectAsync$0(PlainHttpConnection.java:113) > > at java.base/java.security.AccessController.doPrivileged(Native Method) > > at > > java.net.http/jdk.internal.net.http.PlainHttpConnection.connectAsync(PlainHttpConnection.java:115) > > at > > java.net.http/jdk.internal.net.http.Http1Exchange.sendHeadersAsync(Http1Exchange.java:261) > > at > > java.net.http/jdk.internal.net.http.Exchange.lambda$responseAsyncImpl0$8(Exchange.java:385) > > at > > java.net.http/jdk.internal.net.http.Exchange.checkFor407(Exchange.java:320) > > at > > java.net.http/jdk.internal.net.http.Exchange.lambda$responseAsyncImpl0$9(Exchange.java:389) > > at > > java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:930) > > at > > java.base/java.util.concurrent.CompletableFuture.uniHandleStage(CompletableFuture.java:946) > > at > > java.base/java.util.concurrent.CompletableFuture.handle(CompletableFuture.java:2266) > > at > > java.net.http/jdk.internal.net.http.Exchange.responseAsyncImpl0(Exchange.java:389) > > at > > java.net.http/jdk.internal.net.http.Exchange.responseAsyncImpl(Exchange.java:299) > > at > > java.net.http/jdk.internal.net.http.Exchange.responseAsync(Exchange.java:291) > > at > > java.net.http/jdk.internal.net.http.MultiExchange.responseAsyncImpl(MultiExchange.java:240) > > at > > java.net.http/jdk.internal.net.http.MultiExchange.lambda$responseAsync0$1(MultiExchange.java:205) > > at > > java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1072) > > at > > java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506) > > at > > java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1705) > > at > > java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) > > at > > java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) > > at java.base/java.lang.Thread.run(Thread.java:832) > > > > > > It's a different matter that this stacktrace is missing the caller's stack > > frames and that's being tracked in [1]. The javadoc of send method doesn't > > mention anything about what specific exception gets thrown in case of > > connection failures. It does say: > > > > * @throws IllegalArgumentException if the {@code request} argument is > > not > > * a request that could have been validly built as specified by > > {@link > > * HttpRequest.Builder HttpRequest.Builder}. > > > > and the thrown java.nio.channels.UnresolvedAddressException indeed extends > > IllegalArgumentException. However, given that the API itself doesn't say > > anything about exceptions that get thrown on connection failures, adding a > > catch block specifically for java.nio.channels.UnresolvedAddressException > > seems like relying on the implementation detail. Can these APIs make it > > explicit what exception(s) can be expected to be thrown in case of > > connection failures, so that it's part of the contract? > > > > [1] https://bugs.openjdk.java.net/browse/JDK-8203298 > > > > -Jaikiran > > > >