error.hpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. * Copyright (c) 2014, Peter Thorson. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. * * Redistributions of source code must retain the above copyright
  7. * notice, this list of conditions and the following disclaimer.
  8. * * Redistributions in binary form must reproduce the above copyright
  9. * notice, this list of conditions and the following disclaimer in the
  10. * documentation and/or other materials provided with the distribution.
  11. * * Neither the name of the WebSocket++ Project nor the
  12. * names of its contributors may be used to endorse or promote products
  13. * derived from this software without specific prior written permission.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
  19. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. *
  26. */
  27. #ifndef WEBSOCKETPP_ERROR_HPP
  28. #define WEBSOCKETPP_ERROR_HPP
  29. #include <exception>
  30. #include <string>
  31. #include <utility>
  32. #include <websocketpp/common/cpp11.hpp>
  33. #include <websocketpp/common/system_error.hpp>
  34. namespace websocketpp {
  35. /// Combination error code / string type for returning two values
  36. typedef std::pair<lib::error_code,std::string> err_str_pair;
  37. /// Library level error codes
  38. namespace error {
  39. enum value {
  40. /// Catch-all library error
  41. general = 1,
  42. /// send attempted when endpoint write queue was full
  43. send_queue_full,
  44. /// Attempted an operation using a payload that was improperly formatted
  45. /// ex: invalid UTF8 encoding on a text message.
  46. payload_violation,
  47. /// Attempted to open a secure connection with an insecure endpoint
  48. endpoint_not_secure,
  49. /// Attempted an operation that required an endpoint that is no longer
  50. /// available. This is usually because the endpoint went out of scope
  51. /// before a connection that it created.
  52. endpoint_unavailable,
  53. /// An invalid uri was supplied
  54. invalid_uri,
  55. /// The endpoint is out of outgoing message buffers
  56. no_outgoing_buffers,
  57. /// The endpoint is out of incoming message buffers
  58. no_incoming_buffers,
  59. /// The connection was in the wrong state for this operation
  60. invalid_state,
  61. /// Unable to parse close code
  62. bad_close_code,
  63. /// Close code is in a reserved range
  64. reserved_close_code,
  65. /// Close code is invalid
  66. invalid_close_code,
  67. /// Invalid UTF-8
  68. invalid_utf8,
  69. /// Invalid subprotocol
  70. invalid_subprotocol,
  71. /// An operation was attempted on a connection that did not exist or was
  72. /// already deleted.
  73. bad_connection,
  74. /// Unit testing utility error code
  75. test,
  76. /// Connection creation attempted failed
  77. con_creation_failed,
  78. /// Selected subprotocol was not requested by the client
  79. unrequested_subprotocol,
  80. /// Attempted to use a client specific feature on a server endpoint
  81. client_only,
  82. /// Attempted to use a server specific feature on a client endpoint
  83. server_only,
  84. /// HTTP connection ended
  85. http_connection_ended,
  86. /// WebSocket opening handshake timed out
  87. open_handshake_timeout,
  88. /// WebSocket close handshake timed out
  89. close_handshake_timeout,
  90. /// Invalid port in URI
  91. invalid_port,
  92. /// An async accept operation failed because the underlying transport has been
  93. /// requested to not listen for new connections anymore.
  94. async_accept_not_listening,
  95. /// The requested operation was canceled
  96. operation_canceled,
  97. /// Connection rejected
  98. rejected,
  99. /// Upgrade Required. This happens if an HTTP request is made to a
  100. /// WebSocket++ server that doesn't implement an http handler
  101. upgrade_required,
  102. /// Invalid WebSocket protocol version
  103. invalid_version,
  104. /// Unsupported WebSocket protocol version
  105. unsupported_version,
  106. /// HTTP parse error
  107. http_parse_error,
  108. /// Extension negotiation failed
  109. extension_neg_failed
  110. }; // enum value
  111. class category : public lib::error_category {
  112. public:
  113. category() {}
  114. char const * name() const _WEBSOCKETPP_NOEXCEPT_TOKEN_ {
  115. return "websocketpp";
  116. }
  117. std::string message(int value) const {
  118. switch(value) {
  119. case error::general:
  120. return "Generic error";
  121. case error::send_queue_full:
  122. return "send queue full";
  123. case error::payload_violation:
  124. return "payload violation";
  125. case error::endpoint_not_secure:
  126. return "endpoint not secure";
  127. case error::endpoint_unavailable:
  128. return "endpoint not available";
  129. case error::invalid_uri:
  130. return "invalid uri";
  131. case error::no_outgoing_buffers:
  132. return "no outgoing message buffers";
  133. case error::no_incoming_buffers:
  134. return "no incoming message buffers";
  135. case error::invalid_state:
  136. return "invalid state";
  137. case error::bad_close_code:
  138. return "Unable to extract close code";
  139. case error::invalid_close_code:
  140. return "Extracted close code is in an invalid range";
  141. case error::reserved_close_code:
  142. return "Extracted close code is in a reserved range";
  143. case error::invalid_utf8:
  144. return "Invalid UTF-8";
  145. case error::invalid_subprotocol:
  146. return "Invalid subprotocol";
  147. case error::bad_connection:
  148. return "Bad Connection";
  149. case error::test:
  150. return "Test Error";
  151. case error::con_creation_failed:
  152. return "Connection creation attempt failed";
  153. case error::unrequested_subprotocol:
  154. return "Selected subprotocol was not requested by the client";
  155. case error::client_only:
  156. return "Feature not available on server endpoints";
  157. case error::server_only:
  158. return "Feature not available on client endpoints";
  159. case error::http_connection_ended:
  160. return "HTTP connection ended";
  161. case error::open_handshake_timeout:
  162. return "The opening handshake timed out";
  163. case error::close_handshake_timeout:
  164. return "The closing handshake timed out";
  165. case error::invalid_port:
  166. return "Invalid URI port";
  167. case error::async_accept_not_listening:
  168. return "Async Accept not listening";
  169. case error::operation_canceled:
  170. return "Operation canceled";
  171. case error::rejected:
  172. return "Connection rejected";
  173. case error::upgrade_required:
  174. return "Upgrade required";
  175. case error::invalid_version:
  176. return "Invalid version";
  177. case error::unsupported_version:
  178. return "Unsupported version";
  179. case error::http_parse_error:
  180. return "HTTP parse error";
  181. case error::extension_neg_failed:
  182. return "Extension negotiation failed";
  183. default:
  184. return "Unknown";
  185. }
  186. }
  187. };
  188. inline const lib::error_category& get_category() {
  189. static category instance;
  190. return instance;
  191. }
  192. inline lib::error_code make_error_code(error::value e) {
  193. return lib::error_code(static_cast<int>(e), get_category());
  194. }
  195. } // namespace error
  196. } // namespace websocketpp
  197. _WEBSOCKETPP_ERROR_CODE_ENUM_NS_START_
  198. template<> struct is_error_code_enum<websocketpp::error::value>
  199. {
  200. static bool const value = true;
  201. };
  202. _WEBSOCKETPP_ERROR_CODE_ENUM_NS_END_
  203. namespace websocketpp {
  204. class exception : public std::exception {
  205. public:
  206. exception(std::string const & msg, lib::error_code ec = make_error_code(error::general))
  207. : m_msg(msg.empty() ? ec.message() : msg), m_code(ec)
  208. {}
  209. explicit exception(lib::error_code ec)
  210. : m_msg(ec.message()), m_code(ec)
  211. {}
  212. ~exception() throw() {}
  213. virtual char const * what() const throw() {
  214. return m_msg.c_str();
  215. }
  216. lib::error_code code() const throw() {
  217. return m_code;
  218. }
  219. const std::string m_msg;
  220. lib::error_code m_code;
  221. };
  222. } // namespace websocketpp
  223. #endif // WEBSOCKETPP_ERROR_HPP