4949#undef ntohll
5050#undef htonll
5151#endif
52+ #define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
5253#include < websocketpp/config/asio_client.hpp>
5354#include < websocketpp/config/asio_no_tls_client.hpp>
5455#include < websocketpp/client.hpp>
@@ -90,6 +91,17 @@ namespace client
9091namespace details
9192{
9293
94+ // Utility function to build up error string based on error code and location.
95+ static std::string build_error_msg (const std::error_code &ec, const std::string &location)
96+ {
97+ std::string msg (location);
98+ msg.append (" : " );
99+ msg.append (std::to_string (ec.value ()));
100+ msg.append (" : " );
101+ msg.append (ec.message ());
102+ return msg;
103+ }
104+
93105static utility::string_t g_subProtocolHeader (_XPLATSTR(" Sec-WebSocket-Protocol" ));
94106
95107class wspp_client : public _websocket_client_impl , public std ::enable_shared_from_this<wspp_client>
@@ -151,6 +163,7 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
151163 catch (...) {}
152164 break ;
153165 }
166+
154167 // We have released the lock on all paths here
155168 m_service.stop ();
156169 if (m_thread.joinable ())
@@ -225,13 +238,17 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
225238 m_connect_tce.set ();
226239 });
227240
228- client.set_fail_handler ([this ](websocketpp::connection_hdl)
241+ client.set_fail_handler ([this ](websocketpp::connection_hdl con_hdl )
229242 {
230243 _ASSERTE (m_state == CONNECTING);
244+ auto &client = m_client->client <WebsocketConfigType>();
245+ const auto &ec = client.get_con_from_hdl (con_hdl)->get_ec ();
246+ websocket_exception exc (ec, build_error_msg (ec, " set_fail_handler" ));
247+
231248 std::lock_guard<std::mutex> lock (m_receive_queue_lock);
232- close_pending_tasks_with_error ();
249+ close_pending_tasks_with_error (exc );
233250 m_state = CLOSED;
234- m_connect_tce.set_exception (websocket_exception ( " Connection attempt failed. " ) );
251+ m_connect_tce.set_exception (exc );
235252 });
236253
237254 client.set_message_handler ([this ](websocketpp::connection_hdl, const websocketpp::config::asio_client::message_type::ptr &msg)
@@ -278,11 +295,15 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
278295 }
279296 });
280297
281- client.set_close_handler ([this ](websocketpp::connection_hdl)
298+ client.set_close_handler ([this ](websocketpp::connection_hdl con_hdl )
282299 {
283- std::unique_lock<std::mutex> lock (m_receive_queue_lock);
284300 _ASSERTE (m_state != CLOSED);
285- close_pending_tasks_with_error ();
301+ auto &client = m_client->client <WebsocketConfigType>();
302+ const auto &ec = client.get_con_from_hdl (con_hdl)->get_ec ();
303+ websocket_exception exc (ec, build_error_msg (ec, " set_close_handler" ));
304+
305+ std::lock_guard<std::mutex> lock (m_receive_queue_lock);
306+ close_pending_tasks_with_error (exc);
286307 m_close_tce.set ();
287308 m_state = CLOSED;
288309 });
@@ -294,7 +315,7 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
294315 m_con = con;
295316 if (ec.value () != 0 )
296317 {
297- return pplx::task_from_exception<void >(websocket_exception (ec. message ( )));
318+ return pplx::task_from_exception<void >(websocket_exception (ec, build_error_msg (ec, " get_connection " )));
298319 }
299320
300321 // Add any request headers specified by the user.
@@ -316,7 +337,7 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
316337 con->add_subprotocol (utility::conversions::to_utf8string (value), ec);
317338 if (ec.value ())
318339 {
319- return pplx::task_from_exception<void >(websocket_exception (ec. message ( )));
340+ return pplx::task_from_exception<void >(websocket_exception (ec, build_error_msg (ec, " add_subprotocol " )));
320341 }
321342 }
322343 }
@@ -328,12 +349,6 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
328349 {
329350 m_service.run ();
330351 _ASSERTE (m_state == CLOSED);
331- {
332- std::unique_lock<std::mutex> lock (m_receive_queue_lock);
333- close_pending_tasks_with_error ();
334- }
335- _ASSERTE (m_state == CLOSED);
336- return 0 ;
337352 });
338353
339354 return pplx::create_task (m_connect_tce);
@@ -534,10 +549,10 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
534549 try
535550 {
536551 // Catch exceptions from previous tasks, if any and convert it to websocket exception.
537- auto ec = previousTask.get ();
552+ const auto & ec = previousTask.get ();
538553 if (ec.value () != 0 )
539554 {
540- eptr = std::make_exception_ptr (websocket_exception (ec. message ( )));
555+ eptr = std::make_exception_ptr (websocket_exception (ec, build_error_msg (ec, " sending message " )));
541556 }
542557 }
543558 catch (...)
@@ -612,14 +627,14 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
612627 }
613628
614629 // Note: must be called while m_receive_queue_lock is locked.
615- void close_pending_tasks_with_error ()
630+ void close_pending_tasks_with_error (const websocket_exception &exc )
616631 {
617632 while (!m_receive_task_queue.empty ())
618633 {
619634 // There are tasks waiting to receive a message, signal them
620635 auto tce = m_receive_task_queue.front ();
621636 m_receive_task_queue.pop ();
622- tce.set_exception (std::make_exception_ptr (websocket_exception ( " Websocket connection has been closed. " ) ));
637+ tce.set_exception (std::make_exception_ptr (exc ));
623638 }
624639 }
625640
0 commit comments