Skip to content

Commit

Permalink
Include 42108 and 42109 to retriable transient errors list (#1215)
Browse files Browse the repository at this point in the history
* Include 42108 and 42109 to retriable transient errors list

* Update tests
  • Loading branch information
cheenamalhotra committed Aug 23, 2021
1 parent 8b77c49 commit 896c4fc
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,13 @@ internal bool IsDNSCachingBeforeRedirectSupported

// Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later.
// If the problem persists, contact customer support, and provide them the session tracing ID of '%.*ls'.
40613
40613,

// Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again.
42108,

// The SQL pool is warming up. Please try again.
42109
};

internal SessionData CurrentSessionData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ internal SqlInternalConnectionTds(
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.ctor|ADV> {0}, constructed new TDS internal connection", ObjectID);
}

// The erros in the transient error set are contained in
// The errors in the transient error set are contained in
// https://azure.microsoft.com/en-us/documentation/articles/sql-database-develop-error-messages/#transient-faults-connection-loss-and-other-temporary-errors
private static void populateTransientErrors()
{
Expand Down Expand Up @@ -614,6 +614,12 @@ private static void populateTransientErrors()
// Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later.
// If the problem persists, contact customer support, and provide them the session tracing ID of '%.*ls'.
transientErrors.Add(40613);

// Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again.
transientErrors.Add(42108);

// The SQL pool is warming up. Please try again.
transientErrors.Add(42109);
// Do federation errors deserve to be here ?
// Note: Federation errors 10053 and 10054 might also deserve inclusion in your retry logic.
//transientErrors.Add(10053);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ private static readonly HashSet<int> s_defaultTransientErrors
40501, // The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d.
40540, // The service has encountered an error processing your request. Please try again.
40197, // The service has encountered an error processing your request. Please try again. Error code %d.
42108, // Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again.
42109, // The SQL pool is warming up. Please try again.
10929, // Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637. Otherwise, please try again later.
10928, // Resource ID: %d. The %s limit for the database is %d and has been reached. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637.
10060, // An error has occurred while establishing a connection to the server. When connecting to SQL Server, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) (Microsoft SQL Server, Error: 10060)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ internal static SqlRetryLogicBaseProvider CommandProvider
}
}
}

}

internal interface IAppContextSwitchOverridesSection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,67 +17,58 @@ public class SqlConnectionBasicTests
[Fact]
public void ConnectionTest()
{
using (TestTdsServer server = TestTdsServer.StartTestServer())
{
using (SqlConnection connection = new SqlConnection(server.ConnectionString))
{
connection.Open();
}
}
using TestTdsServer server = TestTdsServer.StartTestServer();
using SqlConnection connection = new SqlConnection(server.ConnectionString);
connection.Open();
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))]
[ActiveIssue(4830, TestPlatforms.AnyUnix)]
[PlatformSpecific(TestPlatforms.Windows)]
public void IntegratedAuthConnectionTest()
{
using (TestTdsServer server = TestTdsServer.StartTestServer())
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(server.ConnectionString);
builder.IntegratedSecurity = true;
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
}
}
using TestTdsServer server = TestTdsServer.StartTestServer();
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(server.ConnectionString);
builder.IntegratedSecurity = true;
using SqlConnection connection = new SqlConnection(builder.ConnectionString);
connection.Open();
}

[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))]
[InlineData(40613)]
[InlineData(42108)]
[InlineData(42109)]
[PlatformSpecific(TestPlatforms.Windows)]
public void TransientFaultTest()
public void TransientFaultTest(uint errorCode)
{
using (TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, true, 40613))
using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, true, errorCode);
SqlConnectionStringBuilder builder = new()
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder()
{
DataSource = "localhost," + server.Port,
IntegratedSecurity = true,
Encrypt = false
};
DataSource = "localhost," + server.Port,
IntegratedSecurity = true,
Encrypt = false
};

using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
using SqlConnection connection = new(builder.ConnectionString);
try
{
connection.Open();
Assert.Equal(ConnectionState.Open, connection.State);
}
catch (Exception e)
{
if (null != connection)
{
try
{
connection.Open();
Assert.Equal(ConnectionState.Open, connection.State);
}
catch (Exception e)
{
if (null != connection)
{
Assert.Equal(ConnectionState.Closed, connection.State);
}
Assert.False(true, e.Message);
}
Assert.Equal(ConnectionState.Closed, connection.State);
}
Assert.False(true, e.Message);
}
}

[Fact]
public void SqlConnectionDbProviderFactoryTest()
{
SqlConnection con = new SqlConnection();
SqlConnection con = new();
PropertyInfo dbProviderFactoryProperty = con.GetType().GetProperty("DbProviderFactory", BindingFlags.NonPublic | BindingFlags.Instance);
Assert.NotNull(dbProviderFactoryProperty);
DbProviderFactory factory = dbProviderFactoryProperty.GetValue(con) as DbProviderFactory;
Expand All @@ -104,23 +95,22 @@ public void SqlConnectionEmptyParameters()
Assert.False(new SqlConnectionStringBuilder(con.ConnectionString).IntegratedSecurity);
}

[Fact]
public void SqlConnectionInvalidParameters()
[Theory]
[InlineData("Timeout=null;")]
[InlineData("Timeout= null;")]
[InlineData("Timeout=1 1;")]
[InlineData("Timeout=1a;")]
[InlineData("Integrated Security=truee")]
public void SqlConnectionInvalidParameters(string connString)
{
Assert.Throws<ArgumentException>(() => new SqlConnection("Timeout=null;"));
Assert.Throws<ArgumentException>(() => new SqlConnection("Timeout= null;"));
Assert.Throws<ArgumentException>(() => new SqlConnection("Timeout=1 1;"));
Assert.Throws<ArgumentException>(() => new SqlConnection("Timeout=1a;"));
Assert.Throws<ArgumentException>(() => new SqlConnection("Integrated Security=truee"));
Assert.Throws<ArgumentException>(() => new SqlConnection(connString));
}

[Fact]
public void ClosedConnectionSchemaRetrieval()
{
using (SqlConnection connection = new SqlConnection(string.Empty))
{
Assert.Throws<InvalidOperationException>(() => connection.GetSchema());
}
using SqlConnection connection = new(string.Empty);
Assert.Throws<InvalidOperationException>(() => connection.GetSchema());
}

[Theory]
Expand All @@ -131,7 +121,7 @@ public void ClosedConnectionSchemaRetrieval()
public void RetrieveWorkstationId(string workstation, bool withDispose, bool shouldMatchSetWorkstationId)
{
string connectionString = $"Workstation Id={workstation}";
SqlConnection conn = new SqlConnection(connectionString);
SqlConnection conn = new(connectionString);
if (withDispose)
{
conn.Dispose();
Expand All @@ -144,14 +134,12 @@ public void RetrieveWorkstationId(string workstation, bool withDispose, bool sho
[Fact]
public void ExceptionsWithMinPoolSizeCanBeHandled()
{
string connectionString = $"Data Source={Guid.NewGuid().ToString()};uid=random;pwd=asd;Connect Timeout=2; Min Pool Size=3";
string connectionString = $"Data Source={Guid.NewGuid()};uid=random;pwd=asd;Connect Timeout=2; Min Pool Size=3";
for (int i = 0; i < 2; i++)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
Exception exception = Record.Exception(() => connection.Open());
Assert.True(exception is InvalidOperationException || exception is SqlException, $"Unexpected exception: {exception}");
}
using SqlConnection connection = new(connectionString);
Exception exception = Record.Exception(() => connection.Open());
Assert.True(exception is InvalidOperationException || exception is SqlException, $"Unexpected exception: {exception}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class RetryLogicConfigHelper

private const string SqlRetryLogicTypeName = "Microsoft.Data.SqlClient.SqlRetryLogic";

public const string DefaultTansientErrors = "1204, 1205, 1222, 49918, 49919, 49920, 4060, 4221, 40143, 40613, 40501, 40540, 40197, 10929, 10928, 10060, 10054, 10053, 997, 233, 64, 20, 0, -2, 207, 102, 2812";
public const string DefaultTransientErrors = "1204, 1205, 1222, 49918, 49919, 49920, 4060, 4221, 40143, 40613, 40501, 40540, 40197, 42108, 42109, 10929, 10928, 10060, 10054, 10053, 997, 233, 64, 20, 0, -2, 207, 102, 2812";

private static readonly Random s_random = new Random();

Expand Down Expand Up @@ -151,7 +151,7 @@ public static object ReturnLoaderAndProviders(RetryLogicConfigs cnnCfg, RetryLog
return loaderObj;
}

public static RetryLogicConfigs CreateRandomConfig(string method, string authorizedSqlCondition = null, string transientErrors = DefaultTansientErrors)
public static RetryLogicConfigs CreateRandomConfig(string method, string authorizedSqlCondition = null, string transientErrors = DefaultTransientErrors)
{
TimeSpan start = TimeSpan.Zero;
TimeSpan end = TimeSpan.FromSeconds(60);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ private static readonly HashSet<int> s_defaultTransientErrors
49920, // Cannot process request. Too many operations in progress for subscription "%ld".
4060, // Cannot open database "%.*ls" requested by the login. The login failed.
4221, // Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. The replica is not available for login because row versions are missing for transactions that were in-flight when the replica was recycled. The issue can be resolved by rolling back or committing the active transactions on the primary replica. Occurrences of this condition can be minimized by avoiding long write transactions on the primary.
42108, // Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again.
42109, // The SQL pool is warming up. Please try again.
40143, // The service has encountered an error processing your request. Please try again.
40613, // Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '%.*ls'.
40501, // The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ private static string GetErrorMessage(uint errorNumber)
case 40613:
return "Database on server is not currently available. Please retry the connection later. " +
"If the problem persists, contact customer support, and provide them the session tracing ID.";
case 42108:
return "Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again.";
case 42109:
return "The SQL pool is warming up. Please try again.";
}
return "Unknown server error occurred";
}
Expand Down

0 comments on commit 896c4fc

Please sign in to comment.