Skip to content

chore: use tagged switches to simplify the code (QF1003)#1272

Merged
ysmolski merged 2 commits into
masterfrom
yury/eng-7816-engine-fix-qf1003-issues
Aug 14, 2025
Merged

chore: use tagged switches to simplify the code (QF1003)#1272
ysmolski merged 2 commits into
masterfrom
yury/eng-7816-engine-fix-qf1003-issues

Conversation

@ysmolski

@ysmolski ysmolski commented Aug 14, 2025

Copy link
Copy Markdown
Contributor

https://staticcheck.dev/docs/checks/#QF1003

As a bonus, I have removed panic from gqlSSEConnectionHandler.subscribe.
Added covering tests.

Summary by CodeRabbit

  • New Features

    • Heartbeat behavior for GraphQL subscriptions (ping/pong) covered by tests to improve connection reliability.
  • Improvements

    • SSE error handling strengthened to explicitly surface unexpected payload shapes as internal errors.
  • Tests

    • Subscription tests converted to table-driven format; validate ping/pong, completion, and varied SSE error payloads.
  • Refactor

    • Internal parsing and control-flow reorganized with no public API or behavioral changes.

@coderabbitai

coderabbitai Bot commented Aug 14, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Refactors internal control flow in type parsing and subscription filtering, replaces SSE error-payload branch with a switch that explicitly handles unknown value types by logging and returning an internal error, and converts subscription client test server logic to a switch handling ping/pong and complete messages. No public APIs changed.

Changes

Cohort / File(s) Change summary
Parser control-flow refactor
v2/pkg/astparser/parser.go
Replaced the initial conditional chain in ParseType with a switch on the first token (IDENT, LBRACK); preserves non-null handling and error paths; no semantic/API changes.
SSE handler error-branch switch
v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go
Replaced Array/Object if-else with a switch inside the SSE error-parsing branch; Array/Object logic unchanged; added a default case that logs unexpected value types and sends an internalError on the error channel, then returns.
SSE handler tests — table-driven
v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler_test.go
Replaced single-case error test with a table-driven test enumerating SSE error payload shapes (object, array, primitives); each subtest runs its own server and asserts normalized error handling expectations.
Subscription client test server rewrite
v2/pkg/engine/datasource/graphql_datasource/graphql_subscription_client_test.go
Rewrote test server message handling from if-else to switch with explicit cases for ping and complete messages; ping case signals receipt, sends a pong, then emits a subsequent data message; complete handled in its own case.
Subscription filter refactor
v2/pkg/engine/resolve/subscription_filter.go
Replaced single-segment if-else on SegmentType with a switch (VariableSegmentType, StaticSegmentType); preserves variable lookup, jsonparser mapping, type comparison and stringification; minor comment edits.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bc169ee and b00d98e.

📒 Files selected for processing (2)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go (3 hunks)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go
  • v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler_test.go
⏰ 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). (4)
  • GitHub Check: Build and test (go 1.23 / ubuntu-latest)
  • 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)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch yury/eng-7816-engine-fix-qf1003-issues

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (2)
v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go (1)

161-186: Do not panic on unexpected errors value type; fail gracefully and propagate an internal error

Panic here can take down the goroutine/process and is not appropriate for malformed or non-spec-conforming inputs from upstream. Prefer logging and emitting an internal error on the error channel.

Apply this diff to handle the case safely:

 				case jsonparser.Object:
 					response := []byte(`{"errors":[]}`)
 					response, err = jsonparser.Set(response, val, "errors", "[0]")
 					if err != nil {
 						h.log.Error("failed to set errors", log.Error(err))
 
 						errCh <- []byte(internalError)
 						return
 					}
 					errCh <- response
 					return
-				default:
-					panic(fmt.Sprintf("unexpected value type: %d", valueType))
+				default:
+					// unexpected type for "errors" field; don't crash the handler
+					h.log.Error(fmt.Sprintf("unexpected errors value type: %d", valueType))
+					errCh <- []byte(internalError)
+					return
 				}
v2/pkg/engine/resolve/subscription_filter.go (1)

109-137: Add default case for unknown SegmentType to avoid silent fallthrough

If a new/unknown SegmentType is introduced, valueType remains the zero value (likely NotExist), leading to silent fallthrough and potentially incorrect comparisons. Return an explicit error to surface invalid templates early.

Apply this diff:

 				switch f.Values[i].Segments[0].SegmentType {
 				case VariableSegmentType:
 					value := ctx.Variables.Get(f.Values[i].Segments[0].VariableSourcePath...)
 					if value == nil {
 						return true, nil
 					}
 					switch value.Type() {
 					case astjson.TypeString:
 						valueType = jsonparser.String
 					case astjson.TypeNumber:
 						valueType = jsonparser.Number
 					case astjson.TypeTrue, astjson.TypeFalse:
 						valueType = jsonparser.Boolean
 					case astjson.TypeNull:
 						valueType = jsonparser.Null
 					case astjson.TypeObject:
 						valueType = jsonparser.Object
 					case astjson.TypeArray:
 						valueType = jsonparser.Array
 					default:
 						return true, nil
 					}
 				case StaticSegmentType:
 					_, valueType, _, err = jsonparser.Get(f.Values[i].Segments[0].Data)
 					if err != nil {
 						return true, nil
 					}
+				default:
+					// Defensive: segment type not recognized – surface this as an invalid template
+					return true, InvalidSubscriptionFilterTemplate
 				}
 
 				if valueType != jsonparser.NotExist && expectedDataType != valueType {
 					return true, nil
 				}

Also applies to: 185-186

📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 086793c and dd00c23.

📒 Files selected for processing (4)
  • v2/pkg/astparser/parser.go (1 hunks)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go (3 hunks)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_subscription_client_test.go (1 hunks)
  • v2/pkg/engine/resolve/subscription_filter.go (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
v2/pkg/engine/resolve/subscription_filter.go (1)
v2/pkg/engine/resolve/inputtemplate.go (3)
  • SegmentType (15-15)
  • VariableSegmentType (19-19)
  • StaticSegmentType (18-18)
🔇 Additional comments (1)
v2/pkg/astparser/parser.go (1)

888-901: LGTM: switch-based control flow in ParseType improves readability with identical semantics

The switch cleanly mirrors prior IDENT/LBRACK handling and keeps the error path intact. No functional regressions identified.

@ysmolski ysmolski changed the title chore: use tagged switches to simplify the code chore: use tagged switches to simplify the code (QF1003) Aug 14, 2025
@ysmolski ysmolski force-pushed the yury/eng-7816-engine-fix-qf1003-issues branch from dd00c23 to f1fc942 Compare August 14, 2025 10:26

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go (1)

161-186: Option: handle json null explicitly to avoid treating it as an unexpected type

If upstream sends "errors": null, treating it as "not found" (skip) instead of unexpected can be friendlier. Consider a dedicated case.

Example:

                 switch valueType {
                 case jsonparser.Array:
                     ...
                 case jsonparser.Object:
                     ...
+                case jsonparser.Null:
+                    // treat null like not present; ignore and continue
+                    continue
                 default:
                     ...
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between dd00c23 and f1fc942.

📒 Files selected for processing (4)
  • v2/pkg/astparser/parser.go (1 hunks)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go (3 hunks)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_subscription_client_test.go (1 hunks)
  • v2/pkg/engine/resolve/subscription_filter.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • v2/pkg/astparser/parser.go
  • v2/pkg/engine/datasource/graphql_datasource/graphql_subscription_client_test.go
  • v2/pkg/engine/resolve/subscription_filter.go
⏰ 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). (4)
  • 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)
  • GitHub Check: Build and test (go 1.23 / ubuntu-latest)
🔇 Additional comments (1)
v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go (1)

161-163: Good: switch on valueType simplifies control flow and matches PR intent

Replacing the if/else with a tagged switch on jsonparser.ValueType improves readability and aligns with QF1003. Cases for Array and Object retain prior behavior.

Comment thread v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (4)
v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler_test.go (4)

352-407: Subtests could run in parallel; capture the range variable to avoid the classic gotcha.

Optional, but this shortens runtime and isolates cases. If you add t.Parallel(), also capture tc to avoid closure over the loop variable.

Apply:

-for _, tc := range testCases {
-  t.Run(tc.name, func(t *testing.T) {
+for _, tc := range testCases {
+  tc := tc
+  t.Run(tc.name, func(t *testing.T) {
+    t.Parallel()

365-369: Confirm that sending SSE frames without the "data:" prefix is intentional and supported.

SSE-compliant frames use "data:" (and optionally "event:"). This test intentionally omits "data:", relying on non-standard behavior. If the handler depends on this to exercise the value-type switch, keep it; otherwise, prefer spec-conformant frames to reduce test fragility.

If you decide to make it spec-compliant, adjust as:

-// Send the malformed error message WITHOUT the "data:" prefix
-// This triggers the error parsing logic in the default case
-_, _ = fmt.Fprintf(w, "%s\n\n", tc.errorMessage)
+// Send the error payload as a proper SSE frame
+_, _ = fmt.Fprintf(w, "data: %s\n\n", tc.errorMessage)

372-372: Use t.Cleanup for server shutdown.

Slightly more idiomatic in subtests and guarantees cleanup even if the subtest ends early.

-      defer server.Close()
+      t.Cleanup(server.Close)

396-399: Use JSON-aware equality for robustness.

Comparing JSON as strings is brittle (whitespace, key order). Testify provides JSONEq.

-      assert.Equal(t, 1, len(updater.updates))
-      assert.Equal(t, tc.expectedErr, updater.updates[0])
+      assert.Equal(t, 1, len(updater.updates))
+      assert.JSONEq(t, tc.expectedErr, updater.updates[0])
📜 Review details

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

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f1fc942 and bc169ee.

📒 Files selected for processing (2)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go (3 hunks)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler_test.go (3)
v2/pkg/engine/resolve/context.go (1)
  • NewContext (153-160)
v2/pkg/engine/datasource/graphql_datasource/graphql_subscription_client.go (3)
  • NewGraphQLSubscriptionClient (216-272)
  • WithReadTimeout (128-132)
  • WithLogger (122-126)
v2/pkg/engine/datasource/graphql_datasource/graphql_datasource.go (2)
  • GraphQLSubscriptionOptions (1928-1941)
  • GraphQLBody (1943-1948)
⏰ 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). (5)
  • GitHub Check: lint
  • GitHub Check: Build and test (go 1.23 / ubuntu-latest)
  • 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 (1)
v2/pkg/engine/datasource/graphql_datasource/graphql_sse_handler_test.go (1)

315-350: Good move to a table-driven test; coverage now includes multiple error payload shapes.

The new cases cover object, array, and primitive error values, aligning with the code’s new switch over value types. This improves confidence in the refactor.

@ysmolski ysmolski force-pushed the yury/eng-7816-engine-fix-qf1003-issues branch from bc169ee to b00d98e Compare August 14, 2025 11:38

@StarpTech StarpTech left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@ysmolski ysmolski merged commit 1020056 into master Aug 14, 2025
11 checks passed
@ysmolski ysmolski deleted the yury/eng-7816-engine-fix-qf1003-issues branch August 14, 2025 12:53
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