Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions src/libraries/Common/src/System/Net/NetworkErrorHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ internal static NetworkException MapSocketException(SocketException socketExcept
{
SocketError.AddressAlreadyInUse => NetworkError.EndPointInUse,
SocketError.HostNotFound => NetworkError.HostNotFound,
SocketError.NoData => NetworkError.HostNotFound,
SocketError.ConnectionRefused => NetworkError.ConnectionRefused,
SocketError.OperationAborted => NetworkError.OperationAborted,
SocketError.ConnectionAborted => NetworkError.ConnectionAborted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ public static Connection Connect(string host, int port, CancellationToken cancel
socket.Connect(new DnsEndPoint(host, port));
}
}
catch (SocketException se)
{
socket.Dispose();

// SocketConnectionFactory wraps SocketException in NetworkException. Do the same here.
NetworkException ne = NetworkErrorHelper.MapSocketException(se);

throw CreateWrappedException(ne, host, port, cancellationToken);
}
Comment on lines +64 to +72

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.

Wouldn't it be wise to add a test for this path?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Probably, yeah. I want to get this in so people aren't seeing this in CI.

catch (Exception e)
{
socket.Dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,17 @@ internal static Exception CreateCompatibleException(Exception exception)

private static WebExceptionStatus GetStatusFromExceptionHelper(HttpRequestException ex)
{
SocketException? socketEx = ex.InnerException as SocketException;
NetworkException? networkException = ex.InnerException as NetworkException;

@stephentoub stephentoub Aug 12, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Any concerns about a breaking change here for other consumers of HttpClient? i.e. if WebRequest is fishing out the inner exception and expecting it to be a SocketException and now it's a NetworkException?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's a minor concern, but I'm not sure there's a better option.

Note that this only matters for exceptions that come during Connect, since those are the only ones that have SocketException as the inner exception today. Other exceptions are already IOExceptions.

The ConnectionFactory stuff is generalizing the Connect path so that you can plug in your own transport. In general these can't throw SocketException, and that's what we invented NetworkException for. We could special case SocketConnectionFactory in SocketsHttpHandler, pull out the inner SocketException, and discard the NetworkException, but that means we'll have different exception behavior based on whether you use SocketConnectionFactory or not, which seems bad.

Long-term, a better solution here would be to have distinct HttpRequestException errors like HostNotFound so that a user can inspect it directly and doesn't need to fish out the inner exception. WebRequestException already has this, as you can see here. We've discussed doing this in the past but haven't actually implemented it.


if (socketEx is null)
if (networkException is null)
{
return WebExceptionStatus.UnknownError;
}

WebExceptionStatus status;
switch (socketEx.SocketErrorCode)
switch (networkException.NetworkError)
{
case SocketError.NoData:
Comment thread
geoffkizer marked this conversation as resolved.
case SocketError.HostNotFound:
case NetworkError.HostNotFound:
status = WebExceptionStatus.NameResolutionFailure;
break;
default:
Expand Down