diff --git a/src/SqlAsyncCollector.cs b/src/SqlAsyncCollector.cs
index 221204c09..803587c5e 100644
--- a/src/SqlAsyncCollector.cs
+++ b/src/SqlAsyncCollector.cs
@@ -95,7 +95,7 @@ public SqlAsyncCollector(IConfiguration configuration, SqlAttribute attribute, I
using (SqlConnection connection = BuildConnection(attribute.ConnectionStringSetting, configuration))
{
this._logger.LogDebugWithThreadId("BEGIN OpenSqlAsyncCollectorVerifyDatabaseSupportedConnection");
- connection.Open();
+ connection.OpenAsyncWithSqlErrorHandling(CancellationToken.None).Wait();
this._logger.LogDebugWithThreadId("END OpenSqlAsyncCollectorVerifyDatabaseSupportedConnection");
VerifyDatabaseSupported(connection, logger, CancellationToken.None).Wait();
}
diff --git a/src/SqlBindingUtilities.cs b/src/SqlBindingUtilities.cs
index 29547ee88..e561690ff 100644
--- a/src/SqlBindingUtilities.cs
+++ b/src/SqlBindingUtilities.cs
@@ -203,5 +203,35 @@ public static async Task VerifyDatabaseSupported(SqlConnection connection, ILogg
}
}
}
+
+ ///
+ /// Opens a connection and handles some specific errors if they occur.
+ ///
+ /// The connection to open
+ /// The cancellation token to pass to the OpenAsync call
+ /// The task that will be completed when the connection is made
+ /// Thrown if an error occurred that we want to wrap with more information
+ internal static async Task OpenAsyncWithSqlErrorHandling(this SqlConnection connection, CancellationToken cancellationToken)
+ {
+ try
+ {
+ await connection.OpenAsync(cancellationToken);
+ }
+ catch (Exception e)
+ {
+ SqlException sqlEx = e is AggregateException a ? a.InnerExceptions.OfType().First() :
+ e is SqlException s ? s :
+ null;
+ // Error number for:
+ // A connection was successfully established with the server, but then an error occurred during the login process.
+ // The certificate chain was issued by an authority that is not trusted.
+ // Add on some more information to help the user figure out how to solve it
+ if (sqlEx?.Number == -2146893019)
+ {
+ throw new InvalidOperationException("The default values for encryption on connections have been changed, please review your configuration to ensure you have the correct values for your server. See https://aka.ms/afsqlext-connection for more details.", e);
+ }
+ throw;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/SqlConverters.cs b/src/SqlConverters.cs
index ddb872a1c..48386632e 100644
--- a/src/SqlConverters.cs
+++ b/src/SqlConverters.cs
@@ -180,7 +180,7 @@ public virtual async Task BuildItemFromAttributeAsync(SqlAttribute attri
{
adapter.SelectCommand = command;
this._logger.LogDebugWithThreadId("BEGIN OpenBuildItemFromAttributeAsyncConnection");
- await connection.OpenAsync();
+ await connection.OpenAsyncWithSqlErrorHandling(CancellationToken.None);
this._logger.LogDebugWithThreadId("END OpenBuildItemFromAttributeAsyncConnection");
Dictionary props = connection.AsConnectionProps();
TelemetryInstance.TrackConvert(type, props);
diff --git a/src/TriggerBinding/SqlTriggerListener.cs b/src/TriggerBinding/SqlTriggerListener.cs
index 27b199d08..7171e6e8a 100644
--- a/src/TriggerBinding/SqlTriggerListener.cs
+++ b/src/TriggerBinding/SqlTriggerListener.cs
@@ -122,7 +122,7 @@ public async Task StartAsync(CancellationToken cancellationToken)
using (var connection = new SqlConnection(this._connectionString))
{
this._logger.LogDebugWithThreadId("BEGIN OpenListenerConnection");
- await connection.OpenAsync(cancellationToken);
+ await connection.OpenAsyncWithSqlErrorHandling(cancellationToken);
this._logger.LogDebugWithThreadId("END OpenListenerConnection");
this._telemetryProps.AddConnectionProps(connection);