diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs index cacc27cb1ecc5e..5296684169c59f 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs @@ -77,7 +77,7 @@ private static async ValueTask ConnectAsync(string host, int port, Cance } catch (Exception error) when (!(error is OperationCanceledException)) { - throw CreateWrappedException(error, cancellationToken); + throw CreateWrappedException(error, host, port, cancellationToken); } finally { @@ -101,7 +101,7 @@ private static Stream Connect(string host, int port, CancellationToken cancellat catch (Exception e) { socket.Dispose(); - throw CreateWrappedException(e, cancellationToken); + throw CreateWrappedException(e, host, port, cancellationToken); } return new NetworkStream(socket, ownsSocket: true); @@ -243,18 +243,18 @@ public static async ValueTask ConnectQuicAsync(string host, int if (lastException != null) { - throw CreateWrappedException(lastException, cancellationToken); + throw CreateWrappedException(lastException, host, port, cancellationToken); } // TODO: find correct exception to throw here. throw new HttpRequestException("No host found."); } - private static Exception CreateWrappedException(Exception error, CancellationToken cancellationToken) + private static Exception CreateWrappedException(Exception error, string host, int port, CancellationToken cancellationToken) { 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); } } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs index 3354cfab349bcd..b7b3e60636d75d 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Net.Sockets; using System.Net.Test.Common; using System.Text; using System.Threading; @@ -207,6 +208,20 @@ public async Task GetContentAsync_ErrorStatusCode_ExpectedExceptionThrown(bool w } } + [Fact] + [OuterLoop("Failing connection attempts take long on windows")] + public async Task GetContentAsync_WhenCanNotConnect_ExceptionContainsHostInfo() + { + using Socket portReserver = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + portReserver.Bind(new IPEndPoint(IPAddress.Loopback, 0)); + IPEndPoint ep = (IPEndPoint)portReserver.LocalEndPoint; + + using var client = CreateHttpClient(); + + HttpRequestException ex = await Assert.ThrowsAsync(() => client.GetStreamAsync($"http://localhost:{ep.Port}")); + Assert.Contains($"localhost:{ep.Port}", ex.Message); + } + [Fact] public async Task GetContentAsync_NullResponse_Throws() {