diff --git a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs index 7c17f9bbd..5f08e4051 100644 --- a/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFConnectionIT.cs @@ -2271,6 +2271,45 @@ public void TestUseMultiplePoolsConnectionPoolByDefault() // assert Assert.AreEqual(ConnectionPoolType.MultipleConnectionPool, poolVersion); } + + [Test] + [TestCase("connection_timeout=5;")] + [TestCase("")] + public void TestOpenAsyncThrowExceptionWhenConnectToUnreachableHost(string extraParameters) + { + // arrange + var connectionString = "account=testAccount;user=testUser;password=testPassword;useProxy=true;proxyHost=no.such.pro.xy;proxyPort=8080;" + + extraParameters; + using (var connection = new SnowflakeDbConnection(connectionString)) + { + // act + var thrown = Assert.Throws(() => connection.OpenAsync().Wait()); + + // assert + Assert.IsTrue(thrown.InnerException is TaskCanceledException || thrown.InnerException is SnowflakeDbException); + if (thrown.InnerException is SnowflakeDbException) + SnowflakeDbExceptionAssert.HasErrorCode(thrown.InnerException, SFError.INTERNAL_ERROR); + Assert.AreEqual(ConnectionState.Closed, connection.State); + } + } + + [Test] + public void TestOpenAsyncThrowExceptionWhenOperationIsCancelled() + { + // arrange + var connectionString = "account=testAccount;user=testUser;password=testPassword;useProxy=true;proxyHost=no.such.pro.xy;proxyPort=8080;"; + using (var connection = new SnowflakeDbConnection(connectionString)) + { + var shortCancellation = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + + // act + var thrown = Assert.Throws(() => connection.OpenAsync(shortCancellation.Token).Wait()); + + // assert + Assert.IsInstanceOf(thrown.InnerException); + Assert.AreEqual(ConnectionState.Closed, connection.State); + } + } } } diff --git a/Snowflake.Data/Client/SnowflakeDbConnection.cs b/Snowflake.Data/Client/SnowflakeDbConnection.cs index fc0ba199d..edc4b1e4e 100755 --- a/Snowflake.Data/Client/SnowflakeDbConnection.cs +++ b/Snowflake.Data/Client/SnowflakeDbConnection.cs @@ -322,6 +322,7 @@ public override Task OpenAsync(CancellationToken cancellationToken) { _connectionState = ConnectionState.Closed; logger.Debug("Connection canceled"); + throw new TaskCanceledException("Connecting was cancelled"); } else { @@ -330,8 +331,7 @@ public override Task OpenAsync(CancellationToken cancellationToken) logger.Debug($"Connection open with pooled session: {SfSession.sessionId}"); OnSessionEstablished(); } - }, - cancellationToken); + }, TaskContinuationOptions.None); // this continuation should be executed always (even if the whole operation was canceled) because it sets the proper state of the connection } public Mutex GetArrayBindingMutex()