Skip to content

Add constructor with string for SocketException #69266

@wfurt

Description

@wfurt

Background and motivation

In .NET Framework we used internal constructors to pass additional information (like EndPoint) to SocketException.
For example when Socket.Connect fails we would see something like

SocketException (111): Connection refused 127.0.0.1:54321

This is no longer possible with .NET Core as the SocketException lives in System.Net.Primitives but the use of it comes from System.Net.Sockets and System.Net.NameResolution. So we currently throw derived internal exception like

System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (111): Connection refused [::ffff:127.0.0.1]:54321
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)

System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000001, 11): Resource temporarily unavailable
   at System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, ValueStopwatch stopwatch)
   at System.Net.Dns.GetHostAddresses(String hostNameOrAddress, AddressFamily family)

or we omit additional useful information.

API Proposal

namespace System.Net
{
    public partial class SocketException : System.ComponentModel.Win32Exception
    {
        public SocketException() { }
        public SocketException(int errorCode) { }
+       public SocketException(int errorCode, string? message) { }
}

Alternatives

Instead of string we could add EndPoint as this is only additional information we use. Since we already use EndPoint.ToString(), the string seems more flexible as we may be able to pass in additional info in future.

API Usage

System.Net.Sockets.SocketException (111): Connection refused [::ffff:127.0.0.1]:54321
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP) 

System.Net.Sockets.SocketException (111): Connection refused 127.0.0.1:54321
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) in /home/furt/github/wfurt-runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs:line 1365
   at System.Threading.Tasks.ValueTask.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state) in /home/furt/github/wfurt-runtime/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ValueTask.cs:line 250

System.Net.Sockets.SocketException (00000001, 11): Resource temporarily unavailable
   at System.Net.Dns.GetHostEntryOrAddressesCore(String hostName, Boolean justAddresses, AddressFamily addressFamily, Int64 startingTimestamp)
   at System.Net.Dns.GetHostAddressesCore(String hostName, AddressFamily addressFamily, Int64 startingTimestamp)
   at System.Net.Dns.GetHostAddresses(String hostNameOrAddress, AddressFamily family)
   at System.Net.Dns.GetHostAddresses(String hostNameOrAddress) 

Risks

This is mostly for compatibility and primary use is runtime internals.

PoC and additional discussion is in #68918 and #37150

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions