chore: use tagged switches to simplify the code (QF1003)#1272
Conversation
WalkthroughRefactors 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
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 detailsConfiguration used: CodeRabbit UI 💡 Knowledge Base configuration:
You can enable these settings in your CodeRabbit configuration. 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ 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)
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
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 errorPanic 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 fallthroughIf 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.
📒 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 semanticsThe switch cleanly mirrors prior IDENT/LBRACK handling and keeps the error path intact. No functional regressions identified.
dd00c23 to
f1fc942
Compare
There was a problem hiding this comment.
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 typeIf 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.
📒 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 intentReplacing the if/else with a tagged switch on jsonparser.ValueType improves readability and aligns with QF1003. Cases for Array and Object retain prior behavior.
There was a problem hiding this comment.
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.
📒 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.
and add tests
bc169ee to
b00d98e
Compare
https://staticcheck.dev/docs/checks/#QF1003
As a bonus, I have removed panic from gqlSSEConnectionHandler.subscribe.
Added covering tests.
Summary by CodeRabbit
New Features
Improvements
Tests
Refactor