From 8b69a1fbe5b536195dc01be93f6840374886b671 Mon Sep 17 00:00:00 2001 From: Oleksandr Poliakov Date: Thu, 24 Jul 2025 13:46:06 -0700 Subject: [PATCH 1/4] CSHARP-5661: Fix UnobservedTaskException on socket connecting timeout --- .../Core/Connections/TcpStreamFactory.cs | 6 +++- .../Core/Connections/TcpStreamFactoryTests.cs | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/MongoDB.Driver/Core/Connections/TcpStreamFactory.cs b/src/MongoDB.Driver/Core/Connections/TcpStreamFactory.cs index ae2c1fb69b4..3e435d3fd12 100644 --- a/src/MongoDB.Driver/Core/Connections/TcpStreamFactory.cs +++ b/src/MongoDB.Driver/Core/Connections/TcpStreamFactory.cs @@ -164,7 +164,11 @@ private async Task ConnectAsync(Socket socket, EndPoint endPoint, CancellationTo if (!connectTask.IsCompleted) { - try { socket.Dispose(); } catch { } + try + { + connectTask.IgnoreExceptions(); + socket.Dispose(); + } catch { } cancellationToken.ThrowIfCancellationRequested(); throw new TimeoutException($"Timed out connecting to {endPoint}. Timeout was {_settings.ConnectTimeout}."); diff --git a/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs b/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs index 014f1b6a523..a503bbc6943 100644 --- a/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs +++ b/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs @@ -185,6 +185,42 @@ public void CreateStream_should_connect_to_a_running_server_and_return_a_non_nul stream.Should().NotBeNull(); } + [Fact] + public async Task CreateStream_should_not_produce_unobserved_exceptions_on_timeout() + { + // The idea of the test: we are trying to connect to some host/port (non-localhost) that will definitely reject the connection, + // when specifying very small timeout leads us to the TimeoutException, but also we should ensure there is no Unobserved Task Exception happening. + var subject = new TcpStreamFactory(new TcpStreamSettings(connectTimeout: TimeSpan.FromMilliseconds(1))); + var host = IPAddress.Parse("1.1.1.1"); + var port = 23456; + + GC.Collect(); + + var unobservedTaskExceptionRaised = false; + EventHandler eventHandler = (s, args) => + { + unobservedTaskExceptionRaised = true; + }; + + TaskScheduler.UnobservedTaskException += eventHandler; + + try + { + var exception = await Record.ExceptionAsync(() => subject.CreateStreamAsync(new IPEndPoint(host, port), CancellationToken.None)); + exception.Should().BeOfType(); + + Thread.Sleep(100); + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + finally + { + TaskScheduler.UnobservedTaskException -= eventHandler; + } + + unobservedTaskExceptionRaised.Should().BeFalse(); + } + [Theory] [ParameterAttributeData] public void SocketConfigurator_can_be_used_to_set_keepAlive( From 5285f23e2e287d0f63371bdecf64f48e23b5dd75 Mon Sep 17 00:00:00 2001 From: Oleksandr Poliakov Date: Thu, 24 Jul 2025 13:49:13 -0700 Subject: [PATCH 2/4] update to trigger PR build --- .../Core/Connections/TcpStreamFactoryTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs b/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs index a503bbc6943..5948e1f500c 100644 --- a/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs +++ b/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs @@ -195,7 +195,6 @@ public async Task CreateStream_should_not_produce_unobserved_exceptions_on_timeo var port = 23456; GC.Collect(); - var unobservedTaskExceptionRaised = false; EventHandler eventHandler = (s, args) => { From 083120ea41eeb0b990dee4c29852d57a3d13682a Mon Sep 17 00:00:00 2001 From: Oleksandr Poliakov Date: Thu, 24 Jul 2025 14:12:28 -0700 Subject: [PATCH 3/4] PR --- .../Core/Connections/TcpStreamFactoryTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs b/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs index 5948e1f500c..3493b0edda5 100644 --- a/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs +++ b/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs @@ -188,11 +188,11 @@ public void CreateStream_should_connect_to_a_running_server_and_return_a_non_nul [Fact] public async Task CreateStream_should_not_produce_unobserved_exceptions_on_timeout() { - // The idea of the test: we are trying to connect to some host/port (non-localhost) that will definitely reject the connection, - // when specifying very small timeout leads us to the TimeoutException, but also we should ensure there is no Unobserved Task Exception happening. + // The purpose of this test is to attempt a connection that will reliably be rejected and throw exception the connection. + // By specifying a very short timeout, we expect a TimeoutException to occur before the connection exception. + // This test ensures that the connection exception is observed. var subject = new TcpStreamFactory(new TcpStreamSettings(connectTimeout: TimeSpan.FromMilliseconds(1))); - var host = IPAddress.Parse("1.1.1.1"); - var port = 23456; + var endpoint = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 23456); GC.Collect(); var unobservedTaskExceptionRaised = false; @@ -205,7 +205,7 @@ public async Task CreateStream_should_not_produce_unobserved_exceptions_on_timeo try { - var exception = await Record.ExceptionAsync(() => subject.CreateStreamAsync(new IPEndPoint(host, port), CancellationToken.None)); + var exception = await Record.ExceptionAsync(() => subject.CreateStreamAsync(endpoint, CancellationToken.None)); exception.Should().BeOfType(); Thread.Sleep(100); From f95e743d9a4d5224d7ebd3c3858a3e0367ba6bde Mon Sep 17 00:00:00 2001 From: Oleksandr Poliakov Date: Thu, 24 Jul 2025 14:25:29 -0700 Subject: [PATCH 4/4] PR --- .../Core/Connections/TcpStreamFactoryTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs b/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs index 3493b0edda5..d1cc67d23ca 100644 --- a/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs +++ b/tests/MongoDB.Driver.Tests/Core/Connections/TcpStreamFactoryTests.cs @@ -195,7 +195,9 @@ public async Task CreateStream_should_not_produce_unobserved_exceptions_on_timeo var endpoint = new IPEndPoint(IPAddress.Parse("1.1.1.1"), 23456); GC.Collect(); + GC.WaitForPendingFinalizers(); var unobservedTaskExceptionRaised = false; + EventHandler eventHandler = (s, args) => { unobservedTaskExceptionRaised = true;