This is an automated email from the ASF dual-hosted git repository. cstamas pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
The following commit(s) were added to refs/heads/master by this push: new b6bb29c2 [MRESOLVER-429] Emit more informative message on connection refused (#379) b6bb29c2 is described below commit b6bb29c26b46f642335723bd57ea7df80dba3bef Author: Tamas Cservenak <ta...@cservenak.net> AuthorDate: Mon Nov 27 11:47:40 2023 +0100 [MRESOLVER-429] Emit more informative message on connection refused (#379) By default HTTP Client is quite muted, message is "ConnectException". As this "message enhancement" already happens on a branch that leads to error, the throwing of new exception and "decorating it" really does not matter, as the end result is anyway: resolver invocation failure (in Maven is build failure). --- https://issues.apache.org/jira/browse/MRESOLVER-429 --- maven-resolver-transport-jdk/pom.xml | 15 ++++++ .../aether/transport/jdk/JdkTransporter.java | 43 +++++++++++++----- .../aether/transport/jdk/JdkTransporterTest.java | 53 ++++++++++++++++++++++ 3 files changed, 99 insertions(+), 12 deletions(-) diff --git a/maven-resolver-transport-jdk/pom.xml b/maven-resolver-transport-jdk/pom.xml index aceb9d27..7918a81c 100644 --- a/maven-resolver-transport-jdk/pom.xml +++ b/maven-resolver-transport-jdk/pom.xml @@ -63,6 +63,21 @@ <scope>provided</scope> <optional>true</optional> </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.maven.resolver</groupId> + <artifactId>maven-resolver-test-util</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.maven.resolver</groupId> + <artifactId>maven-resolver-impl</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java b/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java index 783861ec..6197148a 100644 --- a/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java +++ b/maven-resolver-transport-jdk/src/main/java/org/eclipse/aether/transport/jdk/JdkTransporter.java @@ -26,6 +26,7 @@ import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.Authenticator; +import java.net.ConnectException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.PasswordAuthentication; @@ -193,6 +194,12 @@ final class JdkTransporter extends AbstractTransporter { return baseUri.resolve(task.getLocation()); } + private ConnectException enhance(ConnectException connectException) { + ConnectException result = new ConnectException("Connection to " + baseUri.toASCIIString() + " refused"); + result.initCause(connectException); + return result; + } + @Override public int classify(Throwable error) { if (error instanceof JdkException && ((JdkException) error).getStatusCode() == NOT_FOUND) { @@ -208,9 +215,13 @@ final class JdkTransporter extends AbstractTransporter { .timeout(Duration.ofMillis(requestTimeout)) .method("HEAD", HttpRequest.BodyPublishers.noBody()); headers.forEach(request::setHeader); - HttpResponse<Void> response = client.send(request.build(), HttpResponse.BodyHandlers.discarding()); - if (response.statusCode() >= MULTIPLE_CHOICES) { - throw new JdkException(response.statusCode()); + try { + HttpResponse<Void> response = client.send(request.build(), HttpResponse.BodyHandlers.discarding()); + if (response.statusCode() >= MULTIPLE_CHOICES) { + throw new JdkException(response.statusCode()); + } + } catch (ConnectException e) { + throw enhance(e); } } @@ -236,13 +247,17 @@ final class JdkTransporter extends AbstractTransporter { request.header(ACCEPT_ENCODING, "identity"); } - response = client.send(request.build(), HttpResponse.BodyHandlers.ofInputStream()); - if (response.statusCode() >= MULTIPLE_CHOICES) { - if (resume && response.statusCode() == PRECONDITION_FAILED) { - resume = false; - continue; + try { + response = client.send(request.build(), HttpResponse.BodyHandlers.ofInputStream()); + if (response.statusCode() >= MULTIPLE_CHOICES) { + if (resume && response.statusCode() == PRECONDITION_FAILED) { + resume = false; + continue; + } + throw new JdkException(response.statusCode()); } - throw new JdkException(response.statusCode()); + } catch (ConnectException e) { + throw enhance(e); } break; } @@ -325,9 +340,13 @@ final class JdkTransporter extends AbstractTransporter { utilPut(task, Files.newOutputStream(tempFile.getPath()), true); request.method("PUT", HttpRequest.BodyPublishers.ofFile(tempFile.getPath())); - HttpResponse<Void> response = client.send(request.build(), HttpResponse.BodyHandlers.discarding()); - if (response.statusCode() >= MULTIPLE_CHOICES) { - throw new JdkException(response.statusCode()); + try { + HttpResponse<Void> response = client.send(request.build(), HttpResponse.BodyHandlers.discarding()); + if (response.statusCode() >= MULTIPLE_CHOICES) { + throw new JdkException(response.statusCode()); + } + } catch (ConnectException e) { + throw enhance(e); } } } diff --git a/maven-resolver-transport-jdk/src/test/java/org/eclipse/aether/transport/jdk/JdkTransporterTest.java b/maven-resolver-transport-jdk/src/test/java/org/eclipse/aether/transport/jdk/JdkTransporterTest.java new file mode 100644 index 00000000..26666070 --- /dev/null +++ b/maven-resolver-transport-jdk/src/test/java/org/eclipse/aether/transport/jdk/JdkTransporterTest.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.eclipse.aether.transport.jdk; + +import java.net.ConnectException; +import java.net.URI; + +import org.eclipse.aether.internal.test.util.TestUtils; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.spi.connector.transport.PeekTask; +import org.eclipse.aether.spi.connector.transport.Transporter; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * JDK Transport UT. + */ +@SuppressWarnings({"checkstyle:magicnumber"}) +final class JdkTransporterTest { + @Test + void enhanceConnectExceptionMessages() { + String uri = "https://localhost:12345/"; + RemoteRepository remoteRepository = new RemoteRepository.Builder("central", "default", uri).build(); + JdkTransporterFactory factory = new JdkTransporterFactory(); + + try (Transporter transporter = factory.newInstance(TestUtils.newSession(), remoteRepository)) { + transporter.peek(new PeekTask(URI.create("repo/file.txt"))); + fail("This should throw"); + } catch (ConnectException e) { + assertTrue(e.getMessage().contains("Connection to " + uri + " refused"), e.getMessage()); + } catch (Exception e) { + fail("We expect ConnectException"); + } + } +}