< Summary

Information
Class: IceRpc.Transports.SocketExceptionExtensions
Assembly: IceRpc
File(s): /home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc/Transports/SocketExceptionExtensions.cs
Tag: 1321_24790053727
Line coverage
82%
Covered lines: 55
Uncovered lines: 12
Coverable lines: 67
Total lines: 85
Line coverage: 82%
Branch coverage
25%
Covered branches: 7
Total branches: 28
Branch coverage: 25%
Method coverage
100%
Covered methods: 1
Fully covered methods: 0
Total methods: 1
Method coverage: 100%
Full method coverage: 0%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ToIceRpcException(...)25%342880.59%

File(s)

/home/runner/work/icerpc-csharp/icerpc-csharp/src/IceRpc/Transports/SocketExceptionExtensions.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Net.Sockets;
 4
 5namespace IceRpc.Transports;
 6
 7/// <summary>Provides an extension method for <see cref="SocketException"/> to convert it into an <see
 8/// cref="IceRpcException"/>.</summary>
 9public static class SocketExceptionExtensions
 10{
 11    /// <summary>Converts a <see cref="SocketException"/> into an <see cref="IceRpcException" />.</summary>
 12    /// <param name="exception">The exception to convert.</param>
 13    /// <param name="innerException">The inner exception for the <see cref="IceRpcException"/>, when
 14    /// <see langword="null"/> <paramref name="exception"/> is used as the inner exception.</param>
 15    /// <returns>The <see cref="IceRpcException"/> created from the <see cref="SocketException"/>.</returns>
 16    public static IceRpcException ToIceRpcException(this SocketException exception, Exception? innerException = null)
 4117    {
 4118        innerException ??= exception;
 4119        IceRpcError errorCode = exception.SocketErrorCode switch
 4120        {
 4121            // Address is already in use when attempting to bind a listening socket.
 322            SocketError.AddressAlreadyInUse => IceRpcError.AddressInUse,
 4123
 4124            // ConnectionAborted is reported by the OS and is often triggered by the peer or by a network failure.
 025            SocketError.ConnectionAborted => IceRpcError.ConnectionAborted,
 4126
 4127            // Shutdown matches EPIPE and ConnectionReset matches ECONNRESET. Both are the result of the peer
 4128            // closing the connection non-gracefully.
 4129            //
 4130            // EPIPE is returned when writing to a socket that has been closed and the send buffer is empty.
 4131            // ECONNRESET is returned when the connection is reset while data is still pending in the send buffer.
 4132            //
 4133            // In both cases the connection can no longer be used.
 3334            SocketError.ConnectionReset => IceRpcError.ConnectionAborted,
 235            SocketError.Shutdown => IceRpcError.ConnectionAborted,
 4136
 4137            // NetworkReset indicates that an established connection became invalid due to a network event
 4138            // (for example interface reset, Wi-Fi reconnect, VPN reconnect).
 039            SocketError.NetworkReset => IceRpcError.ConnectionAborted,
 4140
 4141            // The server is reachable but no process is listening on the target port.
 242            SocketError.ConnectionRefused => IceRpcError.ConnectionRefused,
 4143
 4144            // These errors indicate the remote server cannot be reached. This includes routing failures,
 4145            // local network failures, OS-level TCP timeouts, and host reachability failures.
 4146            //
 4147            // The TimedOut error refers to the OS TCP stack exhausting SYN retransmissions when
 4148            // attempting to connect — not to IceRPC-level timeouts, which result in
 4149            // OperationCanceledException via CancellationToken.
 4150            //
 4151            // With the async socket API used by IceRPC, these errors occur during connection
 4152            // establishment. On an established TCP connection, the kernel absorbs ICMP errors
 4153            // and retransmits internally; the application sees ConnectionReset (mapped to
 4154            // ConnectionAborted above) rather than these reachability errors.
 4155            //
 4156            // They are grouped as ServerUnreachable because from the RPC perspective the connection
 4157            // cannot be established.
 158            SocketError.HostUnreachable => IceRpcError.ServerUnreachable,
 059            SocketError.NetworkUnreachable => IceRpcError.ServerUnreachable,
 060            SocketError.NetworkDown => IceRpcError.ServerUnreachable,
 061            SocketError.HostDown => IceRpcError.ServerUnreachable,
 062            SocketError.TimedOut => IceRpcError.ServerUnreachable,
 4163
 4164            // Name resolution failures are also mapped to ServerUnreachable so that the connection cache
 4165            // can treat DNS failures and transport reachability failures uniformly and try alternate
 4166            // server addresses.
 4167            //
 4168            // These errors always occur before connection establishment (during name resolution).
 4169            //
 4170            // Some of these errors (for example HostNotFound) are often permanent configuration issues,
 4171            // but IceRPC keeps the public error model small and leaves retry decisions to higher layers.
 072            SocketError.HostNotFound => IceRpcError.ServerUnreachable,
 073            SocketError.TryAgain => IceRpcError.ServerUnreachable,
 074            SocketError.NoRecovery => IceRpcError.ServerUnreachable,
 075            SocketError.NoData => IceRpcError.ServerUnreachable,
 4176
 4177            // Operation was aborted locally, typically due to cancellation or socket disposal.
 078            SocketError.OperationAborted => IceRpcError.OperationAborted,
 4179
 080            _ => IceRpcError.IceRpcError
 4181        };
 82
 4183        return new IceRpcException(errorCode, innerException);
 4184    }
 85}