Improve GraphQL naming conflict error to identify conflicting entities and operations - #3722
Improve GraphQL naming conflict error to identify conflicting entities and operations#3722RubenCerna2079 with Copilot wants to merge 10 commits into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
@copilot Change the PR so that in the output message we don't include the operation names. Also, if possible we want to keep using the hashset we already used before. Try to change the logic as little as possible from what it was before the changes you made in this PR. The only change should be the error message. |
… names, remove ops from message
Done in 3a1f2d0. The changes are now minimal:
New message format: |
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
/azp run |
|
Azure Pipelines: Successfully started running 6 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
Improves configuration-time GraphQL naming conflict diagnostics by augmenting RuntimeConfigValidator.ValidateEntitiesDoNotGenerateDuplicateQueriesOrMutation to track which entity “owns” each generated GraphQL operation name and by updating unit tests to validate the richer error output (including a new unit test for singular/plural auto-entity collisions).
Changes:
- Enhanced duplicate GraphQL operation detection to retain the owning entity per operation and emit a more structured conflict message.
- Updated existing unit tests to assert the new message shape (prefix + both entity names).
- Added a unit test covering
dbo.Categoryvsdbo.Categories(singular/plural collision) behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Core/Configurations/RuntimeConfigValidator.cs | Tracks operation ownership and builds a more detailed GraphQL naming conflict exception message. |
| src/Service.Tests/UnitTests/ConfigValidationUnitTests.cs | Updates duplicate-detection assertions and adds a new unit test for singular/plural auto-entity collisions. |
| else | ||
| { | ||
| operationOwner[pkQueryName] = entityName; | ||
| operationOwner[listQueryName] = entityName; | ||
| operationOwner[createMutationName] = entityName; | ||
| operationOwner[updateMutationName] = entityName; | ||
| operationOwner[deleteMutationName] = entityName; | ||
| if (databaseType is DatabaseType.CosmosDB_NoSQL) | ||
| { | ||
| operationOwner[patchMutationName] = entityName; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
That should not be possible since the if statement that is used previously to this already checks all the possible operationOwners with the name
There was a problem hiding this comment.
Validate only mode can lose operation ownership after an earlier conflict. The || chain mutates graphQLOperationNames incrementally, but operationOwner is populated only in the else block after every Add succeeds.
If an earlier Add succeeds and a later Add fails, the successfully added operation remains in graphQLOperationNames without an owner. Because validate-only mode continues processing, a later entity can collide with that operation and the resulting message omits the actual conflicting entity.
You can repro this with First (Alpha/Shared), Second (Beta/Shared), and Third (Beta/Thirds). Second successfully adds beta_by_pk before failing on Shared, but beta_by_pk is never assigned an owner. Third then conflicts on beta_by_pk, and its recorded error lists only Third instead of identifying Second.
I think we should record ownership immediately for each successful Add, or possibly use the operation-to-owner dictionary as the authoritative duplicate check.
A validate-only regression test should cover this sequence.
…te-graphql-operations' into copilot/fix-duplicate-graphql-operations
|
/azp run |
|
Azure Pipelines: Successfully started running 6 pipeline(s). |
|
/azp run |
|
Azure Pipelines: Successfully started running 6 pipeline(s). |
|
|
||
| if (containsDuplicateOperationNames) | ||
| { | ||
| string entitiesStr = string.IsNullOrEmpty(conflictingEntityName) |
There was a problem hiding this comment.
The new message can report non-conflicting names as shared. entityNamesStr always contains the current entity's singular and plural names, but the message labels both values as names generated by both entities regardless of which operation actually collided.
Isn't this incorrect for singular-only and plural-only conflicts, where the other configured name can be different? Likewise for stored-procedure/table conflicts, where the generated operation fields can collide even though the entities singular and plural type names differ.
I'm thinking we should probably track and display only the generated names that actually conflict, and if the implementation can not retain that information, this section should be removed or reworded so it does not claim both entities generate both displayed names.
| || ((databaseType is DatabaseType.CosmosDB_NoSQL) && !graphQLOperationNames.Add(patchMutationName))) | ||
| { | ||
| containsDuplicateOperationNames = true; | ||
| conflictingEntityName = |
There was a problem hiding this comment.
This lookup reports only the first conflicting owner, but one entity can conflict with different prior entities on different generated names.
For example, if A uses Alpha/Shared, B uses Beta/Betas, and C uses Beta/Shared, C conflicts with B through its singular-derived operations and with A through its plural list query. The current null-coalescing chain reports only B and omits A, so the user may fix the reported conflict only to encounter another startup failure for the same entity.
Could we collect all distinct owners of the conflicting generated names and include every conflicting entity in the diagnostic instead?
There was a problem hiding this comment.
I think the first conflicting is enough. The developers can walk through all errors one by one, until they succeed. It would be a lot of heavy lifting to check for all conflicting errors.
aaronburtle
left a comment
There was a problem hiding this comment.
Looks good once comments are addressed!
Why make this change?
When
autoentitiesincludes tables whose names differ only by singular/plural form (e.g.dbo.Categoryanddbo.Categories), DAB fails startup with a vague error that doesn't identify the other conflicting entity, the generated GraphQL names, or how to resolve the conflict.What is this change?
RuntimeConfigValidator.ValidateEntitiesDoNotGenerateDuplicateQueriesOrMutation: ReplacedHashSet<string>operation tracking withDictionary<string, string>(operation → owning entity). Checks all operations (not short-circuit) to collect every conflicting name, then builds a structured error message including:Before:
After:
How was this tested?
ValidateExceptionForDuplicateQueriesDueToEntityDefinitionshelper to verify both conflicting entity names appear in the messageValidateAutoEntitiesWithSingularPluralNameCollisionGenerateDuplicateQueriescovering the exactdbo.Category/dbo.CategoriesscenarioSample Request(s)
N/A — error message improvement only; no API behavior changes.