Skip to content

fix error mapping in HttpWebRequest to handle NetworkException#40666

Merged
geoffkizer merged 2 commits intodotnet:masterfrom
geoffkizer:fixtest
Aug 12, 2020
Merged

fix error mapping in HttpWebRequest to handle NetworkException#40666
geoffkizer merged 2 commits intodotnet:masterfrom
geoffkizer:fixtest

Conversation

@geoffkizer
Copy link
Contributor

Fixes #40606

HttpWebRequest was specifically looking for a SocketException to detect and map HostNotFound. Change this to look for NetworkException.

Additionally, fix the sync Connect path in HttpClient to also throw NetworkException instead of SocketException.

@ghost
Copy link

ghost commented Aug 11, 2020

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

@geoffkizer
Copy link
Contributor Author

/azp run runtime-libraries outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@geoffkizer
Copy link
Contributor Author

@antonfirsov The sync Connect fix here will need to get ported to your ConnectionFactory change.

Copy link
Contributor

@scalablecory scalablecory left a comment

Choose a reason for hiding this comment

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

lgtm. we might consider mapping the NoData error; I think it is reasonable to handle it as HostNotFound.

@geoffkizer
Copy link
Contributor Author

/azp run runtime-libraries outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Comment on lines +64 to +72
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);
}
Copy link
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
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.

@geoffkizer geoffkizer merged commit 701c5d9 into dotnet:master Aug 12, 2020
private static WebExceptionStatus GetStatusFromExceptionHelper(HttpRequestException ex)
{
SocketException? socketEx = ex.InnerException as SocketException;
NetworkException? networkException = ex.InnerException as NetworkException;
Copy link
Member

@stephentoub stephentoub Aug 12, 2020

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
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.

@karelz karelz added this to the 5.0.0 milestone Aug 18, 2020
@geoffkizer geoffkizer deleted the fixtest branch November 7, 2020 23:40
@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.

Test failure: System.Net.Tests.HttpWebRequestTest_Async.GetResponseAsync_ServerNameNotInDns_ThrowsWebException

6 participants