rmqtt_net/
error.rs

1use bytestring::ByteString;
2use std::num::NonZeroU16;
3
4use serde::{Deserialize, Serialize};
5
6use rmqtt_codec::error::{DecodeError, EncodeError, HandshakeError, ProtocolError, SendPacketError};
7use rmqtt_codec::v5::{DisconnectReasonCode, PublishAckReason, ToReasonCode};
8
9#[derive(Deserialize, Serialize, Debug, Clone, thiserror::Error)]
10pub enum MqttError {
11    /// Handshake error
12    #[error("Mqtt handshake error: {}", _0)]
13    Handshake(#[from] HandshakeError),
14    #[error("Mqtt protocol error: {}", _0)]
15    Protocol(#[from] ProtocolError),
16    /// MQTT decoding error
17    #[error("Decoding error: {0:?}")]
18    Decode(#[from] DecodeError),
19    /// MQTT encoding error
20    #[error("Encoding error: {0:?}")]
21    Encode(#[from] EncodeError),
22    /// Send packet error
23    #[error("Mqtt send packet error: {}", _0)]
24    SendPacket(#[from] SendPacketError),
25    /// Read timeout
26    #[error("Read timeout")]
27    ReadTimeout,
28    /// Write timeout
29    #[error("Write timeout")]
30    WriteTimeout,
31    /// Flush timeout
32    #[error("Flush timeout")]
33    FlushTimeout,
34    /// Close timeout
35    #[error("Close timeout")]
36    CloseTimeout,
37    #[error("{1}")]
38    PublishAckReason(PublishAckReason, ByteString),
39    #[error("service unavailable")]
40    ServiceUnavailable,
41    #[error("invalid protocol")]
42    InvalidProtocol,
43    #[error("too many subscriptions")]
44    TooManySubscriptions,
45    #[error("too many topic levels")]
46    TooManyTopicLevels,
47    #[error("subscription limit reached, {0}")]
48    SubscribeLimited(String),
49    #[error("identifier rejected")]
50    IdentifierRejected,
51    #[error("Provided packet id is in use")]
52    PacketIdInUse(NonZeroU16),
53    #[error("Is None")]
54    None,
55}
56
57impl ToReasonCode for MqttError {
58    fn to_reason_code(&self) -> DisconnectReasonCode {
59        match self {
60            MqttError::Handshake(err) => err.to_reason_code(),
61            MqttError::Protocol(err) => err.to_reason_code(),
62            MqttError::Decode(err) => err.to_reason_code(),
63            MqttError::Encode(err) => err.to_reason_code(),
64            MqttError::SendPacket(err) => err.to_reason_code(),
65            MqttError::ReadTimeout
66            | MqttError::WriteTimeout
67            | MqttError::FlushTimeout
68            | MqttError::CloseTimeout => DisconnectReasonCode::KeepAliveTimeout,
69            MqttError::PublishAckReason(_, _) => DisconnectReasonCode::ImplementationSpecificError,
70            MqttError::ServiceUnavailable => DisconnectReasonCode::ServerBusy,
71            MqttError::InvalidProtocol => DisconnectReasonCode::ProtocolError,
72            MqttError::TooManySubscriptions => DisconnectReasonCode::QuotaExceeded,
73            MqttError::TooManyTopicLevels => DisconnectReasonCode::TopicNameInvalid,
74            MqttError::SubscribeLimited(_) => DisconnectReasonCode::QuotaExceeded,
75            MqttError::IdentifierRejected => DisconnectReasonCode::NotAuthorized,
76            MqttError::PacketIdInUse(_) => DisconnectReasonCode::UnspecifiedError,
77            MqttError::None => DisconnectReasonCode::UnspecifiedError,
78        }
79    }
80}