feat: add ClientClosedReason enum with 16 close reason values
This commit is contained in:
51
src/NATS.Server/ClientClosedReason.cs
Normal file
51
src/NATS.Server/ClientClosedReason.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
namespace NATS.Server;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reason a client connection was closed.
|
||||||
|
/// Corresponds to Go server/client.go ClosedState (subset for single-server scope).
|
||||||
|
/// </summary>
|
||||||
|
public enum ClientClosedReason
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
ClientClosed,
|
||||||
|
AuthenticationTimeout,
|
||||||
|
AuthenticationViolation,
|
||||||
|
TlsHandshakeError,
|
||||||
|
SlowConsumerPendingBytes,
|
||||||
|
SlowConsumerWriteDeadline,
|
||||||
|
WriteError,
|
||||||
|
ReadError,
|
||||||
|
ParseError,
|
||||||
|
StaleConnection,
|
||||||
|
ProtocolViolation,
|
||||||
|
MaxPayloadExceeded,
|
||||||
|
MaxSubscriptionsExceeded,
|
||||||
|
ServerShutdown,
|
||||||
|
MsgHeaderViolation,
|
||||||
|
NoRespondersRequiresHeaders,
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ClientClosedReasonExtensions
|
||||||
|
{
|
||||||
|
public static string ToReasonString(this ClientClosedReason reason) => reason switch
|
||||||
|
{
|
||||||
|
ClientClosedReason.None => "",
|
||||||
|
ClientClosedReason.ClientClosed => "Client Closed",
|
||||||
|
ClientClosedReason.AuthenticationTimeout => "Authentication Timeout",
|
||||||
|
ClientClosedReason.AuthenticationViolation => "Authorization Violation",
|
||||||
|
ClientClosedReason.TlsHandshakeError => "TLS Handshake Error",
|
||||||
|
ClientClosedReason.SlowConsumerPendingBytes => "Slow Consumer (Pending Bytes)",
|
||||||
|
ClientClosedReason.SlowConsumerWriteDeadline => "Slow Consumer (Write Deadline)",
|
||||||
|
ClientClosedReason.WriteError => "Write Error",
|
||||||
|
ClientClosedReason.ReadError => "Read Error",
|
||||||
|
ClientClosedReason.ParseError => "Parse Error",
|
||||||
|
ClientClosedReason.StaleConnection => "Stale Connection",
|
||||||
|
ClientClosedReason.ProtocolViolation => "Protocol Violation",
|
||||||
|
ClientClosedReason.MaxPayloadExceeded => "Maximum Payload Exceeded",
|
||||||
|
ClientClosedReason.MaxSubscriptionsExceeded => "Maximum Subscriptions Exceeded",
|
||||||
|
ClientClosedReason.ServerShutdown => "Server Shutdown",
|
||||||
|
ClientClosedReason.MsgHeaderViolation => "Message Header Violation",
|
||||||
|
ClientClosedReason.NoRespondersRequiresHeaders => "No Responders Requires Headers",
|
||||||
|
_ => reason.ToString(),
|
||||||
|
};
|
||||||
|
}
|
||||||
24
tests/NATS.Server.Tests/ClientClosedReasonTests.cs
Normal file
24
tests/NATS.Server.Tests/ClientClosedReasonTests.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
namespace NATS.Server.Tests;
|
||||||
|
|
||||||
|
public class ClientClosedReasonTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void All_expected_close_reasons_exist()
|
||||||
|
{
|
||||||
|
// Verify all 17 enum values exist and are distinct (None + 16 named reasons)
|
||||||
|
var values = Enum.GetValues<ClientClosedReason>();
|
||||||
|
values.Length.ShouldBe(17);
|
||||||
|
values.Distinct().Count().ShouldBe(17);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(ClientClosedReason.ClientClosed, "Client Closed")]
|
||||||
|
[InlineData(ClientClosedReason.SlowConsumerPendingBytes, "Slow Consumer (Pending Bytes)")]
|
||||||
|
[InlineData(ClientClosedReason.SlowConsumerWriteDeadline, "Slow Consumer (Write Deadline)")]
|
||||||
|
[InlineData(ClientClosedReason.StaleConnection, "Stale Connection")]
|
||||||
|
[InlineData(ClientClosedReason.ServerShutdown, "Server Shutdown")]
|
||||||
|
public void ToReasonString_returns_human_readable_description(ClientClosedReason reason, string expected)
|
||||||
|
{
|
||||||
|
reason.ToReasonString().ShouldBe(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user