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 #[error("Mqtt handshake error: {}", _0)]
13 Handshake(#[from] HandshakeError),
14 #[error("Mqtt protocol error: {}", _0)]
15 Protocol(#[from] ProtocolError),
16 #[error("Decoding error: {0:?}")]
18 Decode(#[from] DecodeError),
19 #[error("Encoding error: {0:?}")]
21 Encode(#[from] EncodeError),
22 #[error("Mqtt send packet error: {}", _0)]
24 SendPacket(#[from] SendPacketError),
25 #[error("Read timeout")]
27 ReadTimeout,
28 #[error("Write timeout")]
30 WriteTimeout,
31 #[error("Flush timeout")]
33 FlushTimeout,
34 #[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}