Skip to content

Commit 23c9c17

Browse files
Fix connection start after connection failure (#79)
1 parent 6e5e108 commit 23c9c17

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

src/signalrclient/connection_impl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,18 @@ namespace signalr
212212
.append(ex.what()));
213213
}
214214
}
215+
try
216+
{
217+
connection->m_disconnect_cts->cancel();
218+
}
219+
catch (const std::exception& ex)
220+
{
221+
if (connection->m_logger.is_enabled(trace_level::warning))
222+
{
223+
connection->m_logger.log(trace_level::warning, std::string("disconnect event threw an exception in start negotiate: ")
224+
.append(ex.what()));
225+
}
226+
}
215227
callback(std::current_exception());
216228
return;
217229
}

test/signalrclienttests/hub_connection_tests.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,78 @@ TEST(start, propogates_exception_from_negotiate)
465465
ASSERT_EQ(connection_state::disconnected, hub_connection.get_connection_state());
466466
}
467467

468+
// regression test: helps ensure internal state is in a working state for connecting again after connection failures
469+
TEST(start, propogates_exception_from_negotiate_and_can_start_again)
470+
{
471+
auto start_count = 0;
472+
auto http_client = std::make_shared<test_http_client>([&start_count](const std::string& url, http_request, cancellation_token) -> http_response
473+
{
474+
start_count++;
475+
if (start_count == 1)
476+
{
477+
throw custom_exception();
478+
}
479+
throw custom_exception("custom exception 2");
480+
});
481+
482+
auto websocket_client = create_test_websocket_client();
483+
auto hub_connection = hub_connection_builder::create("http://fakeuri")
484+
.with_logging(std::make_shared<memory_log_writer>(), trace_level::none)
485+
.with_http_client_factory([http_client](const signalr_client_config& config)
486+
{
487+
http_client->set_scheduler(config.get_scheduler());
488+
return http_client;
489+
})
490+
.with_websocket_factory([websocket_client](const signalr_client_config& config)
491+
{
492+
websocket_client->set_config(config);
493+
return websocket_client;
494+
})
495+
.build();
496+
497+
std::atomic<bool> disconnected { false };
498+
hub_connection.set_disconnected([&disconnected](std::exception_ptr ex)
499+
{
500+
disconnected.store(true);
501+
});
502+
503+
auto mre = manual_reset_event<void>();
504+
hub_connection.start([&mre](std::exception_ptr exception)
505+
{
506+
mre.set(exception);
507+
});
508+
509+
try
510+
{
511+
mre.get();
512+
ASSERT_TRUE(false);
513+
}
514+
catch (const custom_exception& e)
515+
{
516+
ASSERT_STREQ("custom exception", e.what());
517+
}
518+
519+
ASSERT_FALSE(disconnected.load());
520+
521+
hub_connection.start([&mre](std::exception_ptr exception)
522+
{
523+
mre.set(exception);
524+
});
525+
526+
try
527+
{
528+
mre.get();
529+
ASSERT_TRUE(false);
530+
}
531+
catch (const custom_exception& e)
532+
{
533+
ASSERT_STREQ("custom exception 2", e.what());
534+
}
535+
536+
ASSERT_EQ(connection_state::disconnected, hub_connection.get_connection_state());
537+
ASSERT_FALSE(disconnected.load());
538+
}
539+
468540
TEST(stop, stop_stops_connection)
469541
{
470542
auto websocket_client = create_test_websocket_client();

0 commit comments

Comments
 (0)