Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "bugfix",
"category": "Url Connection Client",
"contributor": "",
"description": "Handle unhandled NullPointerException wrapped in RuntimeException when underlying connection fails with URL Connection HTTP Client"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since "handle" is a vague term, we can replace it with something more specific like "treat as IOException to allow a retry" or something like that

}
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,11 @@ private <T> Optional<T> getAndHandle100Bug(Supplier<T> supplier, boolean failOn1
try {
return Optional.ofNullable(supplier.get());
} catch (RuntimeException e) {
if (e.getCause() instanceof NullPointerException) {
throw new UncheckedIOException(new IOException(
"Unexpected RuntimeException wrapping NullPointerException from HttpURLConnection", e));
Comment thread
dagnir marked this conversation as resolved.
Outdated
}

if (!exceptionCausedBy100HandlingBug(e)) {
throw e;
}
Expand Down Expand Up @@ -431,6 +436,12 @@ private static int getResponseCodeSafely(HttpURLConnection connection) throws IO
return connection.getResponseCode();
} catch (NullPointerException e) {
throw new IOException("Unexpected NullPointerException when trying to read response from HttpURLConnection", e);
} catch (RuntimeException e) {
if (e.getCause() instanceof NullPointerException) {
throw new IOException("Unexpected RuntimeException wrapping NullPointerException when trying to "
+ "read response from HttpURLConnection", e);
}
throw e;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
Expand Down Expand Up @@ -75,6 +76,46 @@
.hasCauseInstanceOf(NullPointerException.class);
}

@Test
public void testGetResponseCodeRuntimeExceptionWrappingNpeIsWrappedAsIo() throws Exception {

Check warning on line 80 in http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClientWithCustomCreateWireMockTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the declaration of thrown exception 'java.lang.Exception', as it cannot be thrown from method's body.

See more on https://sonarcloud.io/project/issues?id=aws_aws-sdk-java-v2&issues=AZ23bPQMBBAZJmFr3IXH&open=AZ23bPQMBBAZJmFr3IXH&pullRequest=6894
connectionInterceptor = safeFunction(connection -> new DelegateHttpURLConnection(connection) {
@Override
public int getResponseCode() {
throw new RuntimeException(new NullPointerException("this.http is null"));
}
});

assertThatThrownBy(() -> testForResponseCode(HttpURLConnection.HTTP_OK))
.isInstanceOf(IOException.class)
.hasCauseInstanceOf(RuntimeException.class);
}

@Test
public void testGetOutputStreamRuntimeExceptionWrappingNpeIsWrappedAsIo() throws Exception {

Check warning on line 94 in http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClientWithCustomCreateWireMockTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the declaration of thrown exception 'java.lang.Exception', as it cannot be thrown from method's body.

See more on https://sonarcloud.io/project/issues?id=aws_aws-sdk-java-v2&issues=AZ23bPQMBBAZJmFr3IXI&open=AZ23bPQMBBAZJmFr3IXI&pullRequest=6894
connectionInterceptor = safeFunction(connection -> new DelegateHttpURLConnection(connection) {
@Override
public OutputStream getOutputStream() {
throw new RuntimeException(new NullPointerException("this.http is null"));
}
});

assertThatThrownBy(() -> testForResponseCode(HttpURLConnection.HTTP_OK))
.isInstanceOf(UncheckedIOException.class);
}

@Test
public void testGetInputStreamRuntimeExceptionWrappingNpeIsWrappedAsIo() throws Exception {

Check warning on line 107 in http-clients/url-connection-client/src/test/java/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClientWithCustomCreateWireMockTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the declaration of thrown exception 'java.lang.Exception', as it cannot be thrown from method's body.

See more on https://sonarcloud.io/project/issues?id=aws_aws-sdk-java-v2&issues=AZ23bPQMBBAZJmFr3IXJ&open=AZ23bPQMBBAZJmFr3IXJ&pullRequest=6894
connectionInterceptor = safeFunction(connection -> new DelegateHttpURLConnection(connection) {
@Override
public InputStream getInputStream() {
throw new RuntimeException(new NullPointerException("this.http is null"));
}
});

assertThatThrownBy(() -> testForResponseCode(HttpURLConnection.HTTP_OK))
.isInstanceOf(UncheckedIOException.class);
}

private class DelegateHttpURLConnection extends HttpURLConnection {
private final HttpURLConnection delegate;

Expand Down
Loading