error.hpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. //
  2. // Copyright (c) 2023-2025 Ivica Siladic, Bruno Iljazovic, Korina Simicevic
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BOOST_MQTT5_ERROR_HPP
  8. #define BOOST_MQTT5_ERROR_HPP
  9. #include <boost/asio/error.hpp>
  10. #include <cstdint>
  11. #include <ostream>
  12. #include <string>
  13. namespace boost::mqtt5 {
  14. /**
  15. * \brief A representation of Disconnect Reason Code.
  16. *
  17. * \details Represents all Reason Codes that the Client can send to the Server
  18. * in the \__DISCONNECT\__ packet as the reason for the disconnection.
  19. */
  20. enum class disconnect_rc_e : uint8_t {
  21. /** \brief Close the connection normally. Do not send the Will Message. */
  22. normal_disconnection = 0x00,
  23. /** \brief The Client wishes to disconnect but requires that
  24. the Server also publishes its Will Message. */
  25. disconnect_with_will_message = 0x04
  26. };
  27. namespace detail {
  28. enum class disconnect_rc_e : uint8_t {
  29. normal_disconnection = 0x00,
  30. disconnect_with_will_message = 0x04,
  31. unspecified_error = 0x80,
  32. malformed_packet = 0x81,
  33. protocol_error = 0x82,
  34. implementation_specific_error = 0x83,
  35. topic_name_invalid = 0x90,
  36. receive_maximum_exceeded = 0x93,
  37. topic_alias_invalid = 0x94,
  38. packet_too_large = 0x95,
  39. message_rate_too_high = 0x96,
  40. quota_exceeded = 0x97,
  41. administrative_action = 0x98,
  42. payload_format_invalid = 0x99
  43. };
  44. }
  45. namespace client {
  46. /**
  47. * \brief Defines error codes related to MQTT client.
  48. *
  49. * \details Encapsulates errors that occur on the client side.
  50. */
  51. enum class error : int {
  52. /** \brief The packet is malformed */
  53. malformed_packet = 100,
  54. /** \brief The packet has exceeded the Maximum Packet Size the Server is willing to accept */
  55. packet_too_large,
  56. /** \brief The Client's session does not exist or it has expired */
  57. session_expired,
  58. /** \brief There are no more available Packet Identifiers to use */
  59. pid_overrun,
  60. /** \brief The Topic is invalid and does not conform to the specification */
  61. invalid_topic,
  62. // publish
  63. /** \brief The Server does not support the specified \ref qos_e */
  64. qos_not_supported,
  65. /** \brief The Server does not support retained messages */
  66. retain_not_available,
  67. /** \brief The Client attempted to send a Topic Alias that is greater than Topic Alias Maximum */
  68. topic_alias_maximum_reached,
  69. // subscribe
  70. /** \brief The Server does not support Wildcard Subscriptions */
  71. wildcard_subscription_not_available,
  72. /** \brief The Server does not support this Subscription Identifier */
  73. subscription_identifier_not_available,
  74. /** \brief The Server does not support Shared Subscriptions */
  75. shared_subscription_not_available
  76. };
  77. inline std::string client_error_to_string(error err) {
  78. switch (err) {
  79. case error::malformed_packet:
  80. return "The packet is malformed";
  81. case error::packet_too_large:
  82. return "The packet has exceeded the Maximum Packet Size "
  83. "the Server is willing to accept";
  84. case error::session_expired:
  85. return "The Client's session does not exist or it has expired";
  86. case error::pid_overrun:
  87. return "There are no more available Packet Identifiers to use";
  88. case error::invalid_topic:
  89. return "The Topic is invalid and "
  90. "does not conform to the specification";
  91. case error::qos_not_supported:
  92. return "The Server does not support the specified QoS";
  93. case error::retain_not_available:
  94. return "The Server does not support retained messages";
  95. case error::topic_alias_maximum_reached:
  96. return "The Client attempted to send a Topic Alias "
  97. "that is greater than Topic Alias Maximum";
  98. case error::wildcard_subscription_not_available:
  99. return "The Server does not support Wildcard Subscriptions";
  100. case error::subscription_identifier_not_available:
  101. return "The Server does not support this Subscription Identifier";
  102. case error::shared_subscription_not_available:
  103. return "The Server does not support Shared Subscriptions";
  104. default:
  105. return "Unknown client error";
  106. }
  107. }
  108. struct client_ec_category : public boost::system::error_category {
  109. const char* name() const noexcept override { return "mqtt_client_error"; }
  110. std::string message(int ev) const noexcept override {
  111. return client_error_to_string(static_cast<error>(ev));
  112. }
  113. };
  114. /// Returns the error category associated with \ref client::error.
  115. inline const client_ec_category& get_error_code_category() {
  116. static client_ec_category cat;
  117. return cat;
  118. }
  119. /// Creates an \ref error_code from a \ref client::error.
  120. inline boost::system::error_code make_error_code(error r) {
  121. return { static_cast<int>(r), get_error_code_category() };
  122. }
  123. inline std::ostream& operator<<(std::ostream& os, const error& err) {
  124. os << get_error_code_category().name() << ":" << static_cast<int>(err);
  125. return os;
  126. }
  127. } // end namespace client
  128. } // end namespace boost::mqtt5
  129. namespace boost::system {
  130. template <>
  131. struct is_error_code_enum <boost::mqtt5::client::error> : std::true_type {};
  132. } // end namespace boost::system
  133. #endif // !BOOST_MQTT5_ERROR_HPP