watermelon_proto/
server_error.rs

1use bytestring::ByteString;
2
3#[derive(Debug, PartialEq, Eq, thiserror::Error)]
4pub enum ServerError {
5    #[error("subject is invalid")]
6    InvalidSubject,
7    #[error("permissions violation for publish")]
8    PublishPermissionViolation,
9    #[error("permissions violation for subscription")]
10    SubscribePermissionViolation,
11
12    #[error("unknown protocol operation")]
13    UnknownProtocolOperation,
14
15    #[error("attempted to connect to route port")]
16    ConnectionAttemptedToWrongPort,
17
18    #[error("authorization violation")]
19    AuthorizationViolation,
20    #[error("authorization timeout")]
21    AuthorizationTimeout,
22    #[error("invalid client protocol")]
23    InvalidClientProtocol,
24    #[error("maximum control line exceeded")]
25    MaximumControlLineExceeded,
26    #[error("parser error")]
27    ParseError,
28    #[error("secure connection, tls required")]
29    TlsRequired,
30    #[error("stale connection")]
31    StaleConnection,
32    #[error("maximum connections exceeded")]
33    MaximumConnectionsExceeded,
34    #[error("slow consumer")]
35    SlowConsumer,
36    #[error("maximum payload violation")]
37    MaximumPayloadViolation,
38
39    #[error("unknown error: {raw_message}")]
40    Other { raw_message: ByteString },
41}
42
43impl ServerError {
44    pub fn is_fatal(&self) -> Option<bool> {
45        match self {
46            Self::InvalidSubject
47            | Self::PublishPermissionViolation
48            | Self::SubscribePermissionViolation => Some(false),
49
50            Self::UnknownProtocolOperation
51            | Self::ConnectionAttemptedToWrongPort
52            | Self::AuthorizationViolation
53            | Self::AuthorizationTimeout
54            | Self::InvalidClientProtocol
55            | Self::MaximumControlLineExceeded
56            | Self::ParseError
57            | Self::TlsRequired
58            | Self::StaleConnection
59            | Self::MaximumConnectionsExceeded
60            | Self::SlowConsumer
61            | Self::MaximumPayloadViolation => Some(true),
62
63            Self::Other { .. } => None,
64        }
65    }
66
67    pub(crate) fn parse(raw_message: ByteString) -> Self {
68        const PUBLISH_PERMISSIONS: &str = "Permissions Violation for Publish";
69        const SUBSCRIPTION_PERMISSIONS: &str = "Permissions Violation for Subscription";
70
71        let m = raw_message.trim();
72        if m.eq_ignore_ascii_case("Invalid Subject") {
73            Self::InvalidSubject
74        } else if m.len() > PUBLISH_PERMISSIONS.len()
75            && m[..PUBLISH_PERMISSIONS.len()].eq_ignore_ascii_case(PUBLISH_PERMISSIONS)
76        {
77            Self::PublishPermissionViolation
78        } else if m.len() > SUBSCRIPTION_PERMISSIONS.len()
79            && m[..SUBSCRIPTION_PERMISSIONS.len()].eq_ignore_ascii_case(SUBSCRIPTION_PERMISSIONS)
80        {
81            Self::SubscribePermissionViolation
82        } else if m.eq_ignore_ascii_case("Unknown Protocol Operation") {
83            Self::UnknownProtocolOperation
84        } else if m.eq_ignore_ascii_case("Attempted To Connect To Route Port") {
85            Self::ConnectionAttemptedToWrongPort
86        } else if m.eq_ignore_ascii_case("Authorization Violation") {
87            Self::AuthorizationViolation
88        } else if m.eq_ignore_ascii_case("Authorization Timeout") {
89            Self::AuthorizationTimeout
90        } else if m.eq_ignore_ascii_case("Invalid Client Protocol") {
91            Self::InvalidClientProtocol
92        } else if m.eq_ignore_ascii_case("Maximum Control Line Exceeded") {
93            Self::MaximumControlLineExceeded
94        } else if m.eq_ignore_ascii_case("Parser Error") {
95            Self::ParseError
96        } else if m.eq_ignore_ascii_case("Secure Connection - TLS Required") {
97            Self::TlsRequired
98        } else if m.eq_ignore_ascii_case("Stale Connection") {
99            Self::StaleConnection
100        } else if m.eq_ignore_ascii_case("Maximum Connections Exceeded") {
101            Self::MaximumConnectionsExceeded
102        } else if m.eq_ignore_ascii_case("Slow Consumer") {
103            Self::SlowConsumer
104        } else if m.eq_ignore_ascii_case("Maximum Payload Violation") {
105            Self::MaximumPayloadViolation
106        } else {
107            Self::Other { raw_message }
108        }
109    }
110}