Fix non-actionable error when Active Directory authentication provider is missing#4035
Fix non-actionable error when Active Directory authentication provider is missing#4035apoorvdeshmukh wants to merge 4 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves the developer experience when Active Directory authentication is requested but the Azure authentication provider isn’t available, by throwing a more actionable error that includes package install guidance.
Changes:
- Add a dedicated localized error message for missing Active Directory auth provider with NuGet install instructions.
- Throw the new actionable exception for Active Directory authentication methods when no provider is registered.
- Add unit tests validating the new message for AD auth methods and preserving the generic message for non-AD methods.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlUtilErrorMessageTests.cs | Adds unit coverage for the new actionable AD-provider-missing error message vs. the generic message. |
| src/Microsoft.Data.SqlClient/src/Resources/Strings.resx | Introduces a new localized string resource for the AD-provider-missing scenario. |
| src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs | Adds the generated strongly-typed accessor for the new resource string. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs | Adds a new SQL.CannotFindActiveDirectoryAuthProvider(...) exception factory. |
| src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Connection/SqlConnectionInternal.cs | Switches AD auth methods to throw the new actionable exception when the provider is missing. |
Files not reviewed (1)
- src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs: Language not supported
You can also share your feedback on Copilot code review. Take the survey.
...icrosoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlUtilErrorMessageTests.cs
Outdated
Show resolved
Hide resolved
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4035 +/- ##
==========================================
- Coverage 72.87% 65.04% -7.83%
==========================================
Files 287 282 -5
Lines 43134 66050 +22916
==========================================
+ Hits 31432 42960 +11528
- Misses 11702 23090 +11388
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 5 changed files in this pull request and generated 4 comments.
You can also share your feedback on Copilot code review. Take the survey.
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" | ||
| mimetype="application/x-microsoft.net.object.bytearray.base64"> | ||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework | ||
| object]</value> |
There was a problem hiding this comment.
This PR includes unrelated whitespace/line-wrapping changes in Strings.resx (e.g., Icon1 and schema/resheader entries). These formatting-only edits add noise and increase merge-conflict risk without affecting the functional error-message change. Consider reverting the unrelated reformatting (or moving it to a dedicated PR).
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" | |
| mimetype="application/x-microsoft.net.object.bytearray.base64"> | |
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework | |
| object]</value> | |
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
There was a problem hiding this comment.
Agreed - I'm not sure what auto-formatting you have enabled, but I would advise disabling it all except for trimming trailing whitespace.
| #pragma warning disable 0618 // ActiveDirectoryPassword is obsolete | ||
| if (ConnectionOptions.Authentication >= SqlAuthenticationMethod.ActiveDirectoryPassword | ||
| && ConnectionOptions.Authentication <= SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity) | ||
| #pragma warning restore 0618 |
There was a problem hiding this comment.
The AD-auth detection relies on a numeric range comparison over SqlAuthenticationMethod values (>= ActiveDirectoryPassword and <= ActiveDirectoryWorkloadIdentity). This is brittle because it silently depends on enum value ordering/contiguity and could misclassify methods if the enum changes. Prefer an explicit switch/pattern match listing the AD methods (or a shared helper) so the intent stays correct if the enum evolves.
There was a problem hiding this comment.
Agreed - just list each method explictily here to make it obvious.
| <data name="SQL_CannotFindActiveDirectoryAuthProvider" xml:space="preserve"> | ||
| <value>Cannot find an authentication provider for '{0}'. The 'Microsoft.Data.SqlClient.Extensions.Azure' NuGet package provides default implementations for Active Directory (Entra ID) authentication methods.</value> |
There was a problem hiding this comment.
The new message claims the Azure extensions package "provides default implementations", but it doesn't actually give install instructions (e.g., "Install/Reference the Microsoft.Data.SqlClient.Extensions.Azure package" and/or a link/command). This seems inconsistent with the PR description's claim of "package install instructions" and may still be non-actionable for users.
There was a problem hiding this comment.
Sure, maybe provide the URL to the nuget.org page for the package.
| #pragma warning disable 0618 // ActiveDirectoryPassword is obsolete | ||
| if (ConnectionOptions.Authentication >= SqlAuthenticationMethod.ActiveDirectoryPassword | ||
| && ConnectionOptions.Authentication <= SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity) | ||
| #pragma warning restore 0618 |
There was a problem hiding this comment.
Agreed - just list each method explictily here to make it obvious.
There was a problem hiding this comment.
This diff is enormous. What happened?
There was a problem hiding this comment.
Copilot added some formatting noise which it simply could not fix.
I manually reverted changes but it's taking too long.
Raised #4046 to clean up the changes.
| <data name="Icon1" type="System.Drawing.Icon, System.Drawing" | ||
| mimetype="application/x-microsoft.net.object.bytearray.base64"> | ||
| <value>[base64 mime encoded string representing a byte array form of the .NET Framework | ||
| object]</value> |
There was a problem hiding this comment.
Agreed - I'm not sure what auto-formatting you have enabled, but I would advise disabling it all except for trimming trailing whitespace.
| <data name="SQL_CannotFindActiveDirectoryAuthProvider" xml:space="preserve"> | ||
| <value>Cannot find an authentication provider for '{0}'. The 'Microsoft.Data.SqlClient.Extensions.Azure' NuGet package provides default implementations for Active Directory (Entra ID) authentication methods.</value> |
There was a problem hiding this comment.
Sure, maybe provide the URL to the nuget.org page for the package.
|
|
||
| namespace Microsoft.Data.SqlClient.UnitTests | ||
| { | ||
| public class SqlUtilErrorMessageTests |
There was a problem hiding this comment.
Unit test files/classes should be the same as the class they are testing with "Tests" at the end. There is no SqlUtilErrorMessage class, so please update to correspond to the class that's actually being tested.
| [Fact] | ||
| public void CannotFindAuthProvider_ReturnsGenericMessage() | ||
| { | ||
| Exception exception = global::Microsoft.Data.SqlClient.SQL.CannotFindAuthProvider("SomeCustomAuth"); |
There was a problem hiding this comment.
I'm not familiar with the global:: syntax here. Can we just have a using at the top of the file and access the method like we would in the code?
| [InlineData("ActiveDirectoryMSI")] | ||
| [InlineData("ActiveDirectoryDefault")] | ||
| [InlineData("ActiveDirectoryWorkloadIdentity")] | ||
| public void CannotFindActiveDirectoryAuthProvider_ContainsPackageGuidance(string authMethod) |
There was a problem hiding this comment.
Honestly, I'm not very sure of the value of these tests. They're really just testing whether the exception text returned by the exception helper is right. This doesn't really test the new behavior or the scenario that prompted the change in the first place.
Instead of testing the sqlutil class, test the SqlConnectionInternal class to make sure that if you don't have Azure package loaded, it will tell you to load Azure package. If that's not possible, consider moving the check into SqlUtil class and pass the auth method to it to decide. That could be tested via a unit test here.
There was a problem hiding this comment.
Indeed - these tests apear to be trying to confirm that the SqlUtil functions return ArgumentException instances with some expected text based on the English (default?) strings resources.
I'm not sure if we have any existing tests for things like this.
I'm also not sure if they will pass when the tests are run using other languages.
|
Closing as addressing this via #4046 |
Description
Fixes #3962.
Issues
#3962
Testing
Unit tests added (SqlUtilErrorMessageTests.cs) covering:
AD auth methods return the actionable message with package install instructions
Non-AD auth methods return the existing generic message
All 9 Active Directory authentication modes validated via parameterized test
Guidelines
Please review the contribution guidelines before submitting a pull request: