actix_amqp/server/
errors.rs

1use std::io;
2
3use amqp_codec::{protocol, AmqpCodecError, ProtocolIdError, SaslFrame};
4use bytestring::ByteString;
5use derive_more::Display;
6
7pub use amqp_codec::protocol::Error;
8
9/// Errors which can occur when attempting to handle amqp connection.
10#[derive(Debug, Display)]
11pub enum ServerError<E> {
12    #[display(fmt = "Message handler service error")]
13    /// Message handler service error
14    Service(E),
15    /// Control service init error
16    ControlServiceInit,
17    #[display(fmt = "Amqp error: {}", _0)]
18    /// Amqp error
19    Amqp(AmqpError),
20    #[display(fmt = "Protocol negotiation error: {}", _0)]
21    /// Amqp protocol negotiation error
22    Handshake(ProtocolIdError),
23    /// Amqp handshake timeout
24    HandshakeTimeout,
25    /// Amqp codec error
26    #[display(fmt = "Amqp codec error: {:?}", _0)]
27    Protocol(AmqpCodecError),
28    #[display(fmt = "Protocol error: {}", _0)]
29    /// Amqp protocol error
30    ProtocolError(Error),
31    #[display(fmt = "Expected open frame, got: {:?}", _0)]
32    Unexpected(protocol::Frame),
33    #[display(fmt = "Unexpected sasl frame: {:?}", _0)]
34    UnexpectedSaslFrame(SaslFrame),
35    #[display(fmt = "Unexpected sasl frame body: {:?}", _0)]
36    UnexpectedSaslBodyFrame(protocol::SaslFrameBody),
37    /// Peer disconnect
38    Disconnected,
39    /// Unexpected io error
40    Io(io::Error),
41}
42
43impl<E> Into<protocol::Error> for ServerError<E> {
44    fn into(self) -> protocol::Error {
45        protocol::Error {
46            condition: protocol::AmqpError::InternalError.into(),
47            description: Some(ByteString::from(format!("{}", self))),
48            info: None,
49        }
50    }
51}
52
53impl<E> From<AmqpError> for ServerError<E> {
54    fn from(err: AmqpError) -> Self {
55        ServerError::Amqp(err)
56    }
57}
58
59impl<E> From<AmqpCodecError> for ServerError<E> {
60    fn from(err: AmqpCodecError) -> Self {
61        ServerError::Protocol(err)
62    }
63}
64
65impl<E> From<ProtocolIdError> for ServerError<E> {
66    fn from(err: ProtocolIdError) -> Self {
67        ServerError::Handshake(err)
68    }
69}
70
71impl<E> From<SaslFrame> for ServerError<E> {
72    fn from(err: SaslFrame) -> Self {
73        ServerError::UnexpectedSaslFrame(err)
74    }
75}
76
77impl<E> From<io::Error> for ServerError<E> {
78    fn from(err: io::Error) -> Self {
79        ServerError::Io(err)
80    }
81}
82
83#[derive(Debug, Display)]
84#[display(fmt = "Amqp error: {:?} {:?} ({:?})", err, description, info)]
85pub struct AmqpError {
86    err: protocol::AmqpError,
87    description: Option<ByteString>,
88    info: Option<protocol::Fields>,
89}
90
91impl AmqpError {
92    pub fn new(err: protocol::AmqpError) -> Self {
93        AmqpError {
94            err,
95            description: None,
96            info: None,
97        }
98    }
99
100    pub fn internal_error() -> Self {
101        Self::new(protocol::AmqpError::InternalError)
102    }
103
104    pub fn not_found() -> Self {
105        Self::new(protocol::AmqpError::NotFound)
106    }
107
108    pub fn unauthorized_access() -> Self {
109        Self::new(protocol::AmqpError::UnauthorizedAccess)
110    }
111
112    pub fn decode_error() -> Self {
113        Self::new(protocol::AmqpError::DecodeError)
114    }
115
116    pub fn invalid_field() -> Self {
117        Self::new(protocol::AmqpError::InvalidField)
118    }
119
120    pub fn not_allowed() -> Self {
121        Self::new(protocol::AmqpError::NotAllowed)
122    }
123
124    pub fn not_implemented() -> Self {
125        Self::new(protocol::AmqpError::NotImplemented)
126    }
127
128    pub fn description<T: AsRef<str>>(mut self, text: T) -> Self {
129        self.description = Some(ByteString::from(text.as_ref()));
130        self
131    }
132
133    pub fn set_description(mut self, text: ByteString) -> Self {
134        self.description = Some(text);
135        self
136    }
137}
138
139impl Into<protocol::Error> for AmqpError {
140    fn into(self) -> protocol::Error {
141        protocol::Error {
142            condition: self.err.into(),
143            description: self.description,
144            info: self.info,
145        }
146    }
147}
148
149#[derive(Debug, Display)]
150#[display(fmt = "Link error: {:?} {:?} ({:?})", err, description, info)]
151pub struct LinkError {
152    err: protocol::LinkError,
153    description: Option<ByteString>,
154    info: Option<protocol::Fields>,
155}
156
157impl LinkError {
158    pub fn force_detach() -> Self {
159        LinkError {
160            err: protocol::LinkError::DetachForced,
161            description: None,
162            info: None,
163        }
164    }
165
166    pub fn description<T: AsRef<str>>(mut self, text: T) -> Self {
167        self.description = Some(ByteString::from(text.as_ref()));
168        self
169    }
170
171    pub fn set_description(mut self, text: ByteString) -> Self {
172        self.description = Some(text);
173        self
174    }
175}
176
177impl Into<protocol::Error> for LinkError {
178    fn into(self) -> protocol::Error {
179        protocol::Error {
180            condition: self.err.into(),
181            description: self.description,
182            info: self.info,
183        }
184    }
185}