Skip to content

Commit

Permalink
Fix | Addressing the excepted behavior when error class is greater th…
Browse files Browse the repository at this point in the history
…an 20 on retry connecting (#1953)
  • Loading branch information
JRahnama committed Apr 3, 2023
1 parent 7550d41 commit b534f15
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1416,6 +1416,12 @@ private async Task ReconnectAsync(int timeout)
if (attempt == retryCount - 1)
{
SqlClientEventSource.Log.TryTraceEvent("SqlConnection.ReconnectAsync | Info | Original Client Connection Id {0}, give up reconnection", _originalConnectionId);
if (e.Class >= TdsEnums.FATAL_ERROR_CLASS)
{
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlConnection.ReconnectAsync|INFO> Original ClientConnectionID {0} - Fatal Error occured. Error Class: {1}", _originalConnectionId, e.Class);
// Error Class: 20-25, usually terminates the database connection
InnerConnection.CloseConnection(InnerConnection.Owner, ConnectionFactory);
}
throw SQL.CR_AllAttemptsFailed(e, _originalConnectionId);
}
if (timeout > 0 && ADP.TimerRemaining(commandTimeoutExpiration) < ADP.TimerFromSeconds(ConnectRetryInterval))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,12 @@ private async Task ReconnectAsync(int timeout)
if (attempt == retryCount - 1)
{
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlConnection.ReconnectAsync|INFO> Original ClientConnectionID {0} - give up reconnection", _originalConnectionId);
if (e.Class >= TdsEnums.FATAL_ERROR_CLASS)
{
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlConnection.ReconnectAsync|INFO> Original ClientConnectionID {0} - Fatal Error occured. Error Class: {1}", _originalConnectionId, e.Class);
// Error Class: 20-25, usually terminates the database connection
InnerConnection.CloseConnection(InnerConnection.Owner, ConnectionFactory);
}
throw SQL.CR_AllAttemptsFailed(e, _originalConnectionId);
}
if (timeout > 0 && ADP.TimerRemaining(commandTimeoutExpiration) < ADP.TimerFromSeconds(ConnectRetryInterval))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,38 @@ public class ConnectionExceptionTest
private const string execReaderFailedMessage = "ExecuteReader requires an open and available Connection. The connection's current state is closed.";
private const string orderIdQuery = "select orderid from orders where orderid < 10250";

[Fact]
public void TestConnectionStateWithErrorClass20()
{
using TestTdsServer server = TestTdsServer.StartTestServer();
using SqlConnection conn = new(server.ConnectionString);

conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT 1";
int result = cmd.ExecuteNonQuery();

Assert.Equal(-1, result);
Assert.Equal(System.Data.ConnectionState.Open, conn.State);

server.Dispose();
try
{
int result2 = cmd.ExecuteNonQuery();
}
catch (SqlException ex)
{
Assert.Equal(11, ex.Class);
Assert.NotNull(ex.InnerException);
SqlException innerEx = Assert.IsType<SqlException>(ex.InnerException);
Assert.Equal(20, innerEx.Class);
Assert.StartsWith("A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible.", innerEx.Message);
// Since the server is not accessible driver can close the close the connection
// It is user responsibilty to maintain the connection.
Assert.Equal(System.Data.ConnectionState.Closed, conn.State);
}
}

[Fact]
public void ExceptionTests()
{
Expand Down

0 comments on commit b534f15

Please sign in to comment.