Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SocketHttpHandler: include host+IP information in HttpRequestException #38131

Merged

Conversation

antonfirsov
Copy link
Member

@antonfirsov antonfirsov commented Jun 19, 2020

Fix #1326 by appending host:port info to HttpRequestException's message when connection fails.

Didn't change the inner SocketException, since it would require subclassing SocketException, which would add unnecessary complexity here.

@ghost
Copy link

ghost commented Jun 19, 2020

Tagging subscribers to this area: @dotnet/ncl
Notify danmosemsft if you want to be subscribed.

@@ -205,6 +205,15 @@ public async Task GetContentAsync_ErrorStatusCode_ExpectedExceptionThrown(bool w
}
}

[Fact]
[OuterLoop("Slow - Negative connection test")]
public async Task GetContentAsync_WhenCanNotConnect_ExceptionContainsHostInfo()
Copy link
Member Author

Choose a reason for hiding this comment

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

This should likely belong to a SocketsHttpHandler test, but I'm new to HTTP codebase, and couldn't figure out where. Any suggestion?

Copy link
Member

Choose a reason for hiding this comment

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

I think this is a good enough place for this test.

@@ -205,6 +205,15 @@ public async Task GetContentAsync_ErrorStatusCode_ExpectedExceptionThrown(bool w
}
}

[Fact]
[OuterLoop("Slow - Negative connection test")]
public async Task GetContentAsync_WhenCanNotConnect_ExceptionContainsHostInfo()
Copy link
Member

Choose a reason for hiding this comment

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

I think this is a good enough place for this test.

[OuterLoop("Slow - Negative connection test")]
public async Task GetContentAsync_WhenCanNotConnect_ExceptionContainsHostInfo()
{
using var client = new HttpClient(new SocketsHttpHandler());
Copy link
Member

Choose a reason for hiding this comment

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

In tests, the HttpClient is usually created via CreateHttpClient(), e.g.: using HttpClient httpClient = CreateHttpClient();. Is there any reason here to create it directly?

Copy link
Member Author

Choose a reason for hiding this comment

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

Both questions depend on what we consider to be the SUT. I can't decide what is a good functional unit to test this feature against. HttpClient with default setup or SocketsHttpHandler?

I have no preference, want to go with existing practices.

Copy link
Member

@ManickaP ManickaP Jun 19, 2020

Choose a reason for hiding this comment

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

Well, similarly looking test is here: https://github.com/dotnet/runtime/blob/master/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs#L2667-L2677
But that's a shared test code which gets executed for WinHttpHandler as well.
Maybe it would be sufficient to just add to the existing test something like:

if (!IsWinHttpHandler)
{
    Assert.Contains(expected, exception.Message);
}

Note that we have many such ifs in the shared test code, so this wouldn't be a revolutionary idea.

Copy link
Member Author

@antonfirsov antonfirsov Jun 30, 2020

Choose a reason for hiding this comment

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

Since I don't think it's worth to cover all the cases HttpClientHandlerTest covers, decided to keep the test in HttpClientTest. Added CreateHttpClient() usage.

Copy link
Member

@wfurt wfurt left a comment

Choose a reason for hiding this comment

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

looks generally good to me. I left few comments.

@@ -205,6 +205,15 @@ public async Task GetContentAsync_ErrorStatusCode_ExpectedExceptionThrown(bool w
}
}

[Fact]
[OuterLoop("Slow - Negative connection test")]
Copy link
Member

Choose a reason for hiding this comment

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

why this would be slow if it connects to local host? that should fail quickly, right?

Copy link
Member Author

@antonfirsov antonfirsov Jun 30, 2020

Choose a reason for hiding this comment

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

A failed connection attempt takes long on Windows. AFAIK this is because winsock will retry the connection up to 3 times even with localhost.

Copy link
Member

Choose a reason for hiding this comment

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

how much delay do you see? The tests I was running were still pretty quick. I'm fine with leaving this outerloop.

Copy link
Member Author

Choose a reason for hiding this comment

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

Failing bare Socket connections attempts take almost 2 seconds usually. This test runs even longer for some reason (about 4 seconds on my PC).

{
return CancellationHelper.ShouldWrapInOperationCanceledException(error, cancellationToken) ?
CancellationHelper.CreateOperationCanceledException(error, cancellationToken) :
new HttpRequestException(error.Message, error, RequestRetryType.RetryOnNextProxy);
new HttpRequestException($"{error.Message} {host}:{port}", error, RequestRetryType.RetryOnNextProxy);
Copy link
Member

Choose a reason for hiding this comment

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

How this would look if host is IPv6 address? Do you know if it already comes in with the surrounding []?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, the brackets are being added here:

// TODO https://github.com/dotnet/runtime/issues/25782:
// Uri.IdnHost is missing '[', ']' characters around IPv6 address.
// So, we need to add them manually for now.
IdnHost = uri.HostNameType == UriHostNameType.IPv6 ? "[" + uri.IdnHost + "]" : uri.IdnHost;

@antonfirsov
Copy link
Member Author

/azp run runtime-libraries outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Member

@wfurt wfurt left a comment

Choose a reason for hiding this comment

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

LGTM

@antonfirsov
Copy link
Member Author

/azp run runtime-libraries outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@antonfirsov
Copy link
Member Author

Opened #38945 for the unrelated test failure.

@antonfirsov antonfirsov merged commit 80e954f into dotnet:master Jul 8, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SocketHttpHandler: exception is missing host/port text
5 participants