From 4c419c5a2cb56399ff90662dc88b7e1d8d91a73b Mon Sep 17 00:00:00 2001 From: Davoud Eshtehari Date: Wed, 25 May 2022 19:05:43 -0700 Subject: [PATCH 1/3] fix --- .../SqlClient/SqlInternalConnectionTds.cs | 24 ++++++---------- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 4 +-- .../SqlClient/SqlInternalConnectionTds.cs | 24 ++++++---------- .../src/Microsoft/Data/SqlClient/TdsParser.cs | 4 +-- .../src/Microsoft/Data/Common/AdapterUtil.cs | 28 +++++++++++++++++++ 5 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index dcbc62ef0d..febca67084 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -2421,7 +2421,7 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) // Deal with Msal service exceptions first, retry if 429 received. catch (MsalServiceException serviceException) { - if (429 == serviceException.StatusCode) + if (serviceException.StatusCode == 429) { RetryConditionHeaderValue retryAfter = serviceException.Headers.RetryAfter; if (retryAfter.Delta.HasValue) @@ -2440,9 +2440,15 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) } else { + SqlClientEventSource.Log.TryTraceEvent(" Timeout: {0}", serviceException.ErrorCode); break; } } + else + { + SqlClientEventSource.Log.TryTraceEvent(" {0}", serviceException.ErrorCode); + throw ADP.CreateSqlException(serviceException, ConnectionOptions, this, username); + } } // Deal with normal MsalExceptions. catch (MsalException msalException) @@ -2453,21 +2459,7 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) { SqlClientEventSource.Log.TryTraceEvent(" {0}", msalException.ErrorCode); - // Error[0] - SqlErrorCollection sqlErs = new(); - sqlErs.Add(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, ConnectionOptions.DataSource, StringsHelper.GetString(Strings.SQL_MSALFailure, username, ConnectionOptions.Authentication.ToString("G")), ActiveDirectoryAuthentication.MSALGetAccessTokenFunctionName, 0)); - - // Error[1] - string errorMessage1 = StringsHelper.GetString(Strings.SQL_MSALInnerException, msalException.ErrorCode); - sqlErs.Add(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, ConnectionOptions.DataSource, errorMessage1, ActiveDirectoryAuthentication.MSALGetAccessTokenFunctionName, 0)); - - // Error[2] - if (!string.IsNullOrEmpty(msalException.Message)) - { - sqlErs.Add(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, ConnectionOptions.DataSource, msalException.Message, ActiveDirectoryAuthentication.MSALGetAccessTokenFunctionName, 0)); - } - SqlException exc = SqlException.CreateException(sqlErs, "", this); - throw exc; + throw ADP.CreateSqlException(msalException, ConnectionOptions, this, username); } SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, sleeping {1}[Milliseconds]", ObjectID, sleepInterval); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index cfb1f477f4..59a1b2f772 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -8367,8 +8367,8 @@ internal void TdsLogin(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures /// Type encapsulating a Federated Authentication access token. internal void SendFedAuthToken(SqlFedAuthToken fedAuthToken) { - Debug.Assert(fedAuthToken != null, "fedAuthToken cannot be null"); - Debug.Assert(fedAuthToken.accessToken != null, "fedAuthToken.accessToken cannot be null"); + Trace.Assert(fedAuthToken != null, "fedAuthToken cannot be null"); + Trace.Assert(fedAuthToken.accessToken != null, "fedAuthToken.accessToken cannot be null"); SqlClientEventSource.Log.TryTraceEvent(" Sending federated authentication token"); _physicalStateObj._outputMessageType = TdsEnums.MT_FEDAUTH; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index 616c44a3f4..02bb79d473 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -2859,7 +2859,7 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) // Deal with Msal service exceptions first, retry if 429 received. catch (MsalServiceException serviceException) { - if (429 == serviceException.StatusCode) + if (serviceException.StatusCode == 429) { RetryConditionHeaderValue retryAfter = serviceException.Headers.RetryAfter; if (retryAfter.Delta.HasValue) @@ -2878,9 +2878,15 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) } else { + SqlClientEventSource.Log.TryTraceEvent(" Timeout: {0}", serviceException.ErrorCode); break; } } + else + { + SqlClientEventSource.Log.TryTraceEvent(" {0}", serviceException.ErrorCode); + throw ADP.CreateSqlException(serviceException, ConnectionOptions, this, username); + } } // Deal with normal MsalExceptions. catch (MsalException msalException) @@ -2891,21 +2897,7 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) { SqlClientEventSource.Log.TryTraceEvent(" {0}", msalException.ErrorCode); - // Error[0] - SqlErrorCollection sqlErs = new SqlErrorCollection(); - sqlErs.Add(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, ConnectionOptions.DataSource, StringsHelper.GetString(Strings.SQL_MSALFailure, username, ConnectionOptions.Authentication.ToString("G")), ActiveDirectoryAuthentication.MSALGetAccessTokenFunctionName, 0)); - - // Error[1] - string errorMessage1 = StringsHelper.GetString(Strings.SQL_MSALInnerException, msalException.ErrorCode); - sqlErs.Add(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, ConnectionOptions.DataSource, errorMessage1, ActiveDirectoryAuthentication.MSALGetAccessTokenFunctionName, 0)); - - // Error[2] - if (!string.IsNullOrEmpty(msalException.Message)) - { - sqlErs.Add(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, ConnectionOptions.DataSource, msalException.Message, ActiveDirectoryAuthentication.MSALGetAccessTokenFunctionName, 0)); - } - SqlException exc = SqlException.CreateException(sqlErs, "", this); - throw exc; + throw ADP.CreateSqlException(msalException, ConnectionOptions, this, username); } SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0}, sleeping {1}[Milliseconds]", ObjectID, sleepInterval); diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 9301a3d958..54a32dbae7 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -9247,8 +9247,8 @@ internal void TdsLogin(SqlLogin rec, /// Type encapuslating a Federated Authentication access token. internal void SendFedAuthToken(SqlFedAuthToken fedAuthToken) { - Debug.Assert(fedAuthToken != null, "fedAuthToken cannot be null"); - Debug.Assert(fedAuthToken.accessToken != null, "fedAuthToken.accessToken cannot be null"); + Trace.Assert(fedAuthToken != null, "fedAuthToken cannot be null"); + Trace.Assert(fedAuthToken.accessToken != null, "fedAuthToken.accessToken cannot be null"); SqlClientEventSource.Log.TryTraceEvent(" Sending federated authentication token"); _physicalStateObj._outputMessageType = TdsEnums.MT_FEDAUTH; diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs index d7f6ce7cf0..5fbe55da6d 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -23,6 +23,7 @@ using Microsoft.Data.SqlClient; using Microsoft.Win32; using IsolationLevel = System.Data.IsolationLevel; +using Microsoft.Identity.Client; #if NETFRAMEWORK using Microsoft.SqlServer.Server; @@ -416,6 +417,33 @@ internal static ArgumentException InvalidArgumentLength(string argumentName, int => Argument(StringsHelper.GetString(Strings.ADP_InvalidArgumentLength, argumentName, limit)); internal static ArgumentException MustBeReadOnly(string argumentName) => Argument(StringsHelper.GetString(Strings.ADP_MustBeReadOnly, argumentName)); + + internal static Exception CreateSqlException(MsalException msalException, SqlConnectionString connectionOptions, SqlInternalConnectionTds sender, string username) + { + // Error[0] + SqlErrorCollection sqlErs = new(); + + sqlErs.Add(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, + connectionOptions.DataSource, + StringsHelper.GetString(Strings.SQL_MSALFailure, username, connectionOptions.Authentication.ToString("G")), + ActiveDirectoryAuthentication.MSALGetAccessTokenFunctionName, 0)); + + // Error[1] + string errorMessage1 = StringsHelper.GetString(Strings.SQL_MSALInnerException, msalException.ErrorCode); + sqlErs.Add(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, + connectionOptions.DataSource, errorMessage1, + ActiveDirectoryAuthentication.MSALGetAccessTokenFunctionName, 0)); + + // Error[2] + if (!string.IsNullOrEmpty(msalException.Message)) + { + sqlErs.Add(new SqlError(0, (byte)0x00, (byte)TdsEnums.MIN_ERROR_CLASS, + connectionOptions.DataSource, msalException.Message, + ActiveDirectoryAuthentication.MSALGetAccessTokenFunctionName, 0)); + } + return SqlException.CreateException(sqlErs, "", sender); + } + #endregion #region CommandBuilder, Command, BulkCopy From 8e44f795477df4ded5b58491631eede62e721357 Mon Sep 17 00:00:00 2001 From: Davoud Eshtehari Date: Fri, 27 May 2022 10:29:13 -0700 Subject: [PATCH 2/3] Address comments --- .../Data/SqlClient/SqlInternalConnectionTds.cs | 2 +- .../netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs | 4 ++++ .../netcore/src/Microsoft/Data/SqlClient/TdsParser.cs | 4 ++-- .../netcore/src/Resources/Strings.Designer.cs | 11 ++++++++++- .../netcore/src/Resources/Strings.resx | 5 ++++- .../Data/SqlClient/SqlInternalConnectionTds.cs | 2 +- .../netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs | 5 +++++ .../netfx/src/Microsoft/Data/SqlClient/TdsParser.cs | 4 ++-- .../netfx/src/Resources/Strings.Designer.cs | 11 ++++++++++- .../netfx/src/Resources/Strings.resx | 3 +++ .../src/Microsoft/Data/Common/AdapterUtil.cs | 4 ++-- 11 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index febca67084..1e50194f8d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -2441,7 +2441,7 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) else { SqlClientEventSource.Log.TryTraceEvent(" Timeout: {0}", serviceException.ErrorCode); - break; + throw SQL.ActiveDirectoryTokenRetrievingTimeout(Enum.GetName(typeof(SqlAuthenticationMethod), ConnectionOptions.Authentication), serviceException.ErrorCode, serviceException); } } else diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs index 6c9247b9ef..4aebe4b518 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlUtil.cs @@ -510,6 +510,10 @@ internal static Exception ActiveDirectoryDeviceFlowTimeout() return ADP.TimeoutException(Strings.SQL_Timeout_Active_Directory_DeviceFlow_Authentication); } + internal static Exception ActiveDirectoryTokenRetrievingTimeout(string authenticaton, string errorCode, Exception exception) + { + return ADP.TimeoutException(StringsHelper.GetString(Strings.AAD_Token_Retrieving_Timeout, authenticaton, errorCode, exception?.Message), exception); + } // // SQL.DataCommand diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs index 59a1b2f772..cfb1f477f4 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -8367,8 +8367,8 @@ internal void TdsLogin(SqlLogin rec, TdsEnums.FeatureExtension requestedFeatures /// Type encapsulating a Federated Authentication access token. internal void SendFedAuthToken(SqlFedAuthToken fedAuthToken) { - Trace.Assert(fedAuthToken != null, "fedAuthToken cannot be null"); - Trace.Assert(fedAuthToken.accessToken != null, "fedAuthToken.accessToken cannot be null"); + Debug.Assert(fedAuthToken != null, "fedAuthToken cannot be null"); + Debug.Assert(fedAuthToken.accessToken != null, "fedAuthToken.accessToken cannot be null"); SqlClientEventSource.Log.TryTraceEvent(" Sending federated authentication token"); _physicalStateObj._outputMessageType = TdsEnums.MT_FEDAUTH; diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.Designer.cs b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.Designer.cs index f33751fb08..4f2d1e38c9 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.Designer.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.Designer.cs @@ -19,7 +19,7 @@ namespace System { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Strings { @@ -60,6 +60,15 @@ internal Strings() { } } + /// + /// Looks up a localized string similar to Connection timed out while retrieving an access token using '{0}' authentication method. Last error: {1}: {2}. + /// + internal static string AAD_Token_Retrieving_Timeout { + get { + return ResourceManager.GetString("AAD_Token_Retrieving_Timeout", resourceCulture); + } + } + /// /// Looks up a localized string similar to Specified parameter name '{0}' is not valid.. /// diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.resx b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.resx index bfe5559389..433c6a7684 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.resx +++ b/src/Microsoft.Data.SqlClient/netcore/src/Resources/Strings.resx @@ -1932,4 +1932,7 @@ Parameter '{0}' cannot have Direction Output or InputOutput when EnableOptimizedParameterBinding is enabled on the parent command. - \ No newline at end of file + + Connection timed out while retrieving an access token using '{0}' authentication method. Last error: {1}: {2} + + diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index 02bb79d473..087c01a1e3 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -2879,7 +2879,7 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) else { SqlClientEventSource.Log.TryTraceEvent(" Timeout: {0}", serviceException.ErrorCode); - break; + throw SQL.ActiveDirectoryTokenRetrievingTimeout(Enum.GetName(typeof(SqlAuthenticationMethod), ConnectionOptions.Authentication), serviceException.ErrorCode, serviceException); } } else diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs index 26f1e59fe2..4cd10a988b 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlUtil.cs @@ -656,6 +656,11 @@ static internal Exception ActiveDirectoryDeviceFlowTimeout() return ADP.TimeoutException(Strings.SQL_Timeout_Active_Directory_DeviceFlow_Authentication); } + internal static Exception ActiveDirectoryTokenRetrievingTimeout(string authenticaton, string errorCode, Exception exception) + { + return ADP.TimeoutException(StringsHelper.GetString(Strings.AAD_Token_Retrieving_Timeout, authenticaton, errorCode, exception?.Message), exception); + } + // // SQL.DataCommand // diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs index 54a32dbae7..9301a3d958 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs @@ -9247,8 +9247,8 @@ internal void TdsLogin(SqlLogin rec, /// Type encapuslating a Federated Authentication access token. internal void SendFedAuthToken(SqlFedAuthToken fedAuthToken) { - Trace.Assert(fedAuthToken != null, "fedAuthToken cannot be null"); - Trace.Assert(fedAuthToken.accessToken != null, "fedAuthToken.accessToken cannot be null"); + Debug.Assert(fedAuthToken != null, "fedAuthToken cannot be null"); + Debug.Assert(fedAuthToken.accessToken != null, "fedAuthToken.accessToken cannot be null"); SqlClientEventSource.Log.TryTraceEvent(" Sending federated authentication token"); _physicalStateObj._outputMessageType = TdsEnums.MT_FEDAUTH; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.Designer.cs b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.Designer.cs index 6e145ddb30..81ad596a68 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.Designer.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.Designer.cs @@ -19,7 +19,7 @@ namespace System { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Strings { @@ -60,6 +60,15 @@ internal Strings() { } } + /// + /// Looks up a localized string similar to Connection timed out while retrieving an access token using '{0}' authentication method. Last error: {1}: {2}. + /// + internal static string AAD_Token_Retrieving_Timeout { + get { + return ResourceManager.GetString("AAD_Token_Retrieving_Timeout", resourceCulture); + } + } + /// /// Looks up a localized string similar to Data adapter mapping error.. /// diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.resx b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.resx index a2b8f976e2..15459d6059 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.resx +++ b/src/Microsoft.Data.SqlClient/netfx/src/Resources/Strings.resx @@ -4617,4 +4617,7 @@ Parameter '{0}' cannot have Direction Output or InputOutput when EnableOptimizedParameterBinding is enabled on the parent command. + + Connection timed out while retrieving an access token using '{0}' authentication method. Last error: {1}: {2} + diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs index 5fbe55da6d..b3b83f816e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs @@ -215,9 +215,9 @@ internal static OverflowException Overflow(string error, Exception inner) return e; } - internal static TimeoutException TimeoutException(string error) + internal static TimeoutException TimeoutException(string error, Exception inner = null) { - TimeoutException e = new(error); + TimeoutException e = new(error, inner); TraceExceptionAsReturnValue(e); return e; } From 349c39a131e1b92801bc48e8631f17c4178f62ca Mon Sep 17 00:00:00 2001 From: Davoud Eshtehari Date: Fri, 3 Jun 2022 17:58:25 -0700 Subject: [PATCH 3/3] Address comments --- .../src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs | 5 ++++- .../src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index 1e50194f8d..e73c5eb96c 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -103,6 +103,9 @@ public void AssertUnrecoverableStateCountIsCorrect() internal sealed class SqlInternalConnectionTds : SqlInternalConnection, IDisposable { + // https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/retry-after#simple-retry-for-errors-with-http-error-codes-500-600 + internal const int MsalHttpRetryStatusCode = 429; + // CONNECTION AND STATE VARIABLES private readonly SqlConnectionPoolGroupProviderInfo _poolGroupProviderInfo; // will only be null when called for ChangePassword, or creating SSE User Instance private TdsParser _parser; @@ -2421,7 +2424,7 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) // Deal with Msal service exceptions first, retry if 429 received. catch (MsalServiceException serviceException) { - if (serviceException.StatusCode == 429) + if (serviceException.StatusCode == MsalHttpRetryStatusCode) { RetryConditionHeaderValue retryAfter = serviceException.Headers.RetryAfter; if (retryAfter.Delta.HasValue) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs index 087c01a1e3..371d52cb56 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs @@ -105,6 +105,8 @@ public void AssertUnrecoverableStateCountIsCorrect() sealed internal class SqlInternalConnectionTds : SqlInternalConnection, IDisposable { + // https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/retry-after#simple-retry-for-errors-with-http-error-codes-500-600 + internal const int MsalHttpRetryStatusCode = 429; // Connection re-route limit internal const int _maxNumberOfRedirectRoute = 10; @@ -2859,7 +2861,7 @@ internal SqlFedAuthToken GetFedAuthToken(SqlFedAuthInfo fedAuthInfo) // Deal with Msal service exceptions first, retry if 429 received. catch (MsalServiceException serviceException) { - if (serviceException.StatusCode == 429) + if (serviceException.StatusCode == MsalHttpRetryStatusCode) { RetryConditionHeaderValue retryAfter = serviceException.Headers.RetryAfter; if (retryAfter.Delta.HasValue)