49
49
#undef ntohll
50
50
#undef htonll
51
51
#endif
52
+ #define _WEBSOCKETPP_CPP11_SYSTEM_ERROR_
52
53
#include < websocketpp/config/asio_client.hpp>
53
54
#include < websocketpp/config/asio_no_tls_client.hpp>
54
55
#include < websocketpp/client.hpp>
@@ -90,6 +91,17 @@ namespace client
90
91
namespace details
91
92
{
92
93
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
+
93
105
static utility::string_t g_subProtocolHeader (_XPLATSTR(" Sec-WebSocket-Protocol" ));
94
106
95
107
class 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
151
163
catch (...) {}
152
164
break ;
153
165
}
166
+
154
167
// We have released the lock on all paths here
155
168
m_service.stop ();
156
169
if (m_thread.joinable ())
@@ -225,13 +238,17 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
225
238
m_connect_tce.set ();
226
239
});
227
240
228
- client.set_fail_handler ([this ](websocketpp::connection_hdl)
241
+ client.set_fail_handler ([this ](websocketpp::connection_hdl con_hdl )
229
242
{
230
243
_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
+
231
248
std::lock_guard<std::mutex> lock (m_receive_queue_lock);
232
- close_pending_tasks_with_error ();
249
+ close_pending_tasks_with_error (exc );
233
250
m_state = CLOSED;
234
- m_connect_tce.set_exception (websocket_exception ( " Connection attempt failed. " ) );
251
+ m_connect_tce.set_exception (exc );
235
252
});
236
253
237
254
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
278
295
}
279
296
});
280
297
281
- client.set_close_handler ([this ](websocketpp::connection_hdl)
298
+ client.set_close_handler ([this ](websocketpp::connection_hdl con_hdl )
282
299
{
283
- std::unique_lock<std::mutex> lock (m_receive_queue_lock);
284
300
_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);
286
307
m_close_tce.set ();
287
308
m_state = CLOSED;
288
309
});
@@ -294,7 +315,7 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
294
315
m_con = con;
295
316
if (ec.value () != 0 )
296
317
{
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 " )));
298
319
}
299
320
300
321
// Add any request headers specified by the user.
@@ -316,7 +337,7 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
316
337
con->add_subprotocol (utility::conversions::to_utf8string (value), ec);
317
338
if (ec.value ())
318
339
{
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 " )));
320
341
}
321
342
}
322
343
}
@@ -328,12 +349,6 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
328
349
{
329
350
m_service.run ();
330
351
_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 ;
337
352
});
338
353
339
354
return pplx::create_task (m_connect_tce);
@@ -534,10 +549,10 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
534
549
try
535
550
{
536
551
// Catch exceptions from previous tasks, if any and convert it to websocket exception.
537
- auto ec = previousTask.get ();
552
+ const auto & ec = previousTask.get ();
538
553
if (ec.value () != 0 )
539
554
{
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 " )));
541
556
}
542
557
}
543
558
catch (...)
@@ -612,14 +627,14 @@ class wspp_client : public _websocket_client_impl, public std::enable_shared_fro
612
627
}
613
628
614
629
// 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 )
616
631
{
617
632
while (!m_receive_task_queue.empty ())
618
633
{
619
634
// There are tasks waiting to receive a message, signal them
620
635
auto tce = m_receive_task_queue.front ();
621
636
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 ));
623
638
}
624
639
}
625
640
0 commit comments