Skip to content

fix: return parsing error for empty selection sets#1220

Merged
jensneuse merged 2 commits intomasterfrom
jens/eng-7565
Jul 9, 2025
Merged

fix: return parsing error for empty selection sets#1220
jensneuse merged 2 commits intomasterfrom
jens/eng-7565

Conversation

@jensneuse
Copy link
Copy Markdown
Member

@jensneuse jensneuse commented Jul 9, 2025

Summary by CodeRabbit

  • Tests

    • Added new tests to verify error handling for empty GraphQL fragments and updated test cases to include non-empty selection sets in operations.
    • Enhanced error reporting tests for empty fragment definitions.
    • Adjusted test inputs to align with updated parsing and validation rules, including removal of certain directive placement tests and updating queries to include minimal field selections.
  • Bug Fixes

    • Improved error reporting for empty selection sets in GraphQL queries by explicitly reporting unexpected tokens.

@jensneuse jensneuse requested review from a team, Noroth, StarpTech and devsergiy as code owners July 9, 2025 11:44
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 9, 2025

Walkthrough

This change set introduces additional tests for handling empty GraphQL fragments in federation integration, updates parser logic to explicitly report errors on empty selection sets, and adjusts related tests to align with the new behavior. Multiple test cases across validation, parsing, and JSON schema modules are updated to use non-empty selection sets, and new test data files for empty fragment queries are added.

Changes

Files/Groups Change Summary
execution/engine/federation_integration_test.go Added two subtests for empty fragment queries, asserting HTTP 500 and empty response body.
execution/federationtesting/testdata/queries/empty_fragment.graphql
.../empty_fragment_variant.graphql
Added test queries defining empty fragments and fragment variants for use in integration tests.
v2/pkg/ast/ast_operation_definition_test.go
v2/pkg/graphqljsonschema/jsonschema_test.go
Updated test cases to use non-empty selection sets in operation definitions.
v2/pkg/astparser/parser.go Modified parser to explicitly report an error when encountering empty selection sets, instead of silent failure.
v2/pkg/astparser/parser_test.go Updated test inputs for type definitions and added a test for error reporting on empty fragments.
v2/pkg/astvalidation/operation_validation_test.go Removed two directive location tests; updated variable input type tests to use non-empty selection sets.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
execution/engine/federation_integration_test.go (1)

367-385: Consider refactoring to reduce code duplication.

Both empty fragment tests follow identical patterns except for the query file names. Consider using a table-driven test approach to reduce duplication.

-	t.Run("empty fragment", func(t *testing.T) {
-		setup := federationtesting.NewFederationSetup(addGateway(false))
-		t.Cleanup(setup.Close)
-		gqlClient := NewGraphqlClient(http.DefaultClient)
-		ctx, cancel := context.WithCancel(context.Background())
-		t.Cleanup(cancel)
-		resp := gqlClient.QueryStatusCode(ctx, setup.GatewayServer.URL, testQueryPath("queries/empty_fragment.graphql"), nil, http.StatusInternalServerError, t)
-		assert.Len(t, resp, 0)
-	})
-
-	t.Run("empty fragment variant", func(t *testing.T) {
-		setup := federationtesting.NewFederationSetup(addGateway(false))
-		t.Cleanup(setup.Close)
-		gqlClient := NewGraphqlClient(http.DefaultClient)
-		ctx, cancel := context.WithCancel(context.Background())
-		t.Cleanup(cancel)
-		resp := gqlClient.QueryStatusCode(ctx, setup.GatewayServer.URL, testQueryPath("queries/empty_fragment_variant.graphql"), nil, http.StatusInternalServerError, t)
-		assert.Len(t, resp, 0)
-	})
+	emptyFragmentTests := []struct {
+		name      string
+		queryFile string
+	}{
+		{"empty fragment", "queries/empty_fragment.graphql"},
+		{"empty fragment variant", "queries/empty_fragment_variant.graphql"},
+	}
+
+	for _, tt := range emptyFragmentTests {
+		t.Run(tt.name, func(t *testing.T) {
+			setup := federationtesting.NewFederationSetup(addGateway(false))
+			t.Cleanup(setup.Close)
+			gqlClient := NewGraphqlClient(http.DefaultClient)
+			ctx, cancel := context.WithCancel(context.Background())
+			t.Cleanup(cancel)
+			resp := gqlClient.QueryStatusCode(ctx, setup.GatewayServer.URL, testQueryPath(tt.queryFile), nil, http.StatusInternalServerError, t)
+			assert.Len(t, resp, 0)
+		})
+	}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 272a2f4 and e00bdfd.

📒 Files selected for processing (8)
  • execution/engine/federation_integration_test.go (1 hunks)
  • execution/federationtesting/testdata/queries/empty_fragment.graphql (1 hunks)
  • execution/federationtesting/testdata/queries/empty_fragment_variant.graphql (1 hunks)
  • v2/pkg/ast/ast_operation_definition_test.go (1 hunks)
  • v2/pkg/astparser/parser.go (1 hunks)
  • v2/pkg/astparser/parser_test.go (3 hunks)
  • v2/pkg/astvalidation/operation_validation_test.go (1 hunks)
  • v2/pkg/graphqljsonschema/jsonschema_test.go (18 hunks)
🧰 Additional context used
🧠 Learnings (1)
execution/engine/federation_integration_test.go (1)
Learnt from: SkArchon
PR: wundergraph/graphql-go-tools#1203
File: v2/pkg/engine/resolve/loader.go:63-67
Timestamp: 2025-07-02T15:28:02.122Z
Learning: In the graphql-go-tools codebase, result structs are consistently initialized with non-nil bytes.Buffer instances, making additional nil checks for res.out unnecessary defensive programming.
🧬 Code Graph Analysis (2)
v2/pkg/astparser/parser.go (1)
v2/pkg/ast/ast.go (1)
  • InvalidRef (8-8)
v2/pkg/astparser/parser_test.go (1)
v2/pkg/astparser/parser.go (1)
  • ParseGraphqlDocumentString (37-45)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build and test (go 1.23 / windows-latest)
  • GitHub Check: Build and test (go 1.23 / windows-latest)
  • GitHub Check: Build and test (go 1.23 / ubuntu-latest)
🔇 Additional comments (11)
execution/federationtesting/testdata/queries/empty_fragment.graphql (1)

1-5: LGTM! Test data file correctly demonstrates empty fragment case.

This test file appropriately defines an empty fragment to validate the parser's error handling for empty selection sets. The fragment A has no fields, which should trigger the new error reporting behavior in the parser.

v2/pkg/astparser/parser.go (1)

1313-1316: Excellent improvement! Parser now explicitly reports empty selection set errors.

This change transforms silent failures into proper error reporting. When encountering an empty selection set, the parser now:

  1. Calls errUnexpectedToken with appropriate expected tokens (IDENT, SPREAD)
  2. Returns ast.InvalidRef instead of 0 to indicate failure

This aligns perfectly with the PR objective of returning parsing errors for empty selection sets.

v2/pkg/graphqljsonschema/jsonschema_test.go (1)

53-53: Systematic and necessary updates to comply with new parser behavior.

All test cases have been consistently updated to replace empty selection sets with { a }, ensuring compatibility with the new parser validation rules. These changes:

  • Maintain test validity while adding minimal required field selections
  • Are applied uniformly across all affected test cases
  • Don't alter the core test logic or expected results
  • Align with the PR objective of rejecting empty selection sets

The minimal field selection is appropriate since these tests focus on input validation rather than query execution.

Also applies to: 65-65, 93-93, 107-107, 123-123, 139-139, 152-152, 165-165, 176-176, 188-188, 204-204, 221-221, 240-240, 260-260, 276-276, 290-290, 297-297, 309-309, 322-322

v2/pkg/ast/ast_operation_definition_test.go (1)

33-33: Necessary test updates to maintain compatibility with stricter parser rules.

The test cases have been properly updated to include non-empty selection sets while preserving the original test logic for operation name existence checking. The changes:

  • Replace empty operation bodies with minimal field selections
  • Maintain the test's core functionality
  • Use appropriate field names for testing purposes
  • Ensure compliance with the new parser validation rules

Also applies to: 39-39, 45-45

execution/federationtesting/testdata/queries/empty_fragment_variant.graphql (1)

1-9: LGTM! Additional test coverage for empty inline fragments.

This test file provides valuable coverage for empty inline fragment scenarios. The fragment A contains an empty inline fragment ... { } which should trigger the parser's error reporting for empty selection sets. This complements the other empty fragment test file and ensures comprehensive validation coverage.

execution/engine/federation_integration_test.go (2)

367-375: LGTM! Proper integration test for empty fragment error handling.

The test correctly verifies that empty fragments result in HTTP 500 Internal Server Error responses with empty bodies, which aligns with the PR objectives of making the parser explicitly report errors on empty selection sets.


377-385: LGTM! Consistent test pattern for empty fragment variant.

The test follows the same structure as the previous empty fragment test and properly validates the error response.

v2/pkg/astvalidation/operation_validation_test.go (1)

3536-3544: LGTM! Necessary adaptation to new parser behavior.

The addition of { a } field selections to these queries is a proper adjustment to maintain test functionality while implementing the new parser behavior that disallows empty selection sets. The test intent (validating variable input types) remains unchanged, and the validation expectations are preserved.

v2/pkg/astparser/parser_test.go (3)

781-800: LGTM: Test inputs updated to use valid GraphQL syntax

The modifications correctly update the test inputs to include minimal field definitions instead of empty braces, which aligns with the stricter parsing behavior for empty selection sets. The changes are appropriate:

  • Type, interface, and input extensions now include a: Int field
  • Scalar extension correctly removes braces (scalars don't have selection sets)
  • Union extension syntax remains unchanged as expected

2234-2245: LGTM: Index test updated with minimal valid content

The changes appropriately update the test definitions to include minimal valid content instead of empty braces:

  • Object types, interfaces, and input types now include a: Int field
  • Enums now include single values (A, B) instead of empty braces
  • Scalars remain without braces as expected

These modifications ensure the test continues to validate the indexing functionality while conforming to the stricter parser behavior for empty selection sets.


2587-2601: LGTM: New test case correctly validates empty fragment error reporting

This test case effectively validates the new parser behavior for empty selection sets:

  • Tests the specific case of empty fragment definition (fragment A on Query {})
  • Verifies the parser reports the expected error message about unexpected RBRACE token
  • Error message correctly indicates that IDENT or SPREAD tokens are expected instead
  • Follows the established pattern of other error reporting tests in the same function

This directly supports the PR objective to "return parsing error for empty selection sets" and ensures the feature works as intended.

Comment thread execution/engine/federation_integration_test.go
@jensneuse jensneuse merged commit 726c0d2 into master Jul 9, 2025
11 checks passed
@jensneuse jensneuse deleted the jens/eng-7565 branch July 9, 2025 12:14
jensneuse pushed a commit that referenced this pull request Jul 9, 2025
🤖 I have created a release *beep* *boop*
---


##
[2.0.0-rc.202](v2.0.0-rc.201...v2.0.0-rc.202)
(2025-07-09)


### Bug Fixes

* return parsing error for empty selection sets
([#1220](#1220))
([726c0d2](726c0d2))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed an issue where empty selection sets during parsing now correctly
return a parsing error.

* **Documentation**
  * Updated the changelog with details for version 2.0.0-rc.202.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants