Skip to content

🐛 Address Copilot comments: JSON body validation, SSE comment, error chains#4170

Merged
clubanderson merged 1 commit intomainfrom
fix/copilot-hour-batch
Apr 1, 2026
Merged

🐛 Address Copilot comments: JSON body validation, SSE comment, error chains#4170
clubanderson merged 1 commit intomainfrom
fix/copilot-hour-batch

Conversation

@clubanderson
Copy link
Copy Markdown
Collaborator

Summary

Addresses Copilot review comments from PRs #4157, #4158, #4159:

  • server.go: Remove ContentLength != 0 guard that skipped validation for chunked transfers. Now decodes r.Body when present, tolerates io.EOF for empty bodies. Returns JSON (not plain text) on /predictions/analyze 400 errors.
  • sse.go: Fix comment — namespace is always included in cache key, not conditionally.
  • gateway.go: Use errors.Join() instead of fmt.Errorf("%v", errs) for unwrappable error chains.

- server.go: Remove ContentLength!=0 guard — use Body!=nil with
  io.EOF tolerance for empty bodies. JSON error response instead of
  plain text on /predictions/analyze (#4157)
- sse.go: Fix comment to reflect namespace is always in cache key
  (#4157)
- gateway.go: Use errors.Join for unwrappable error chains (#4159)

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Copilot AI review requested due to automatic review settings April 1, 2026 14:24
@clubanderson clubanderson merged commit 46d56a1 into main Apr 1, 2026
@kubestellar-prow kubestellar-prow bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Apr 1, 2026
@kubestellar-prow
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign mikespreitzer for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubestellar-prow kubestellar-prow bot deleted the fix/copilot-hour-batch branch April 1, 2026 14:24
@netlify
Copy link
Copy Markdown

netlify bot commented Apr 1, 2026

Deploy Preview for kubestellarconsole canceled.

Name Link
🔨 Latest commit f6649b6
🔍 Latest deploy log https://app.netlify.com/projects/kubestellarconsole/deploys/69cd2a981860030008b2233e

@kubestellar-prow kubestellar-prow bot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Apr 1, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates several handler and client behaviors to address prior review feedback: body validation on chunked/empty requests, JSON error format consistency, corrected SSE cache-key documentation, and improved error-chain composition.

Changes:

  • Decode and validate optional JSON request bodies even for chunked/empty bodies (tolerating io.EOF), and return JSON on 400s for /predictions/analyze.
  • Fix SSE cache-key comment to reflect that namespace is always part of the key (even when empty).
  • Replace %v formatting of multi-errors with errors.Join() for better error chaining.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
pkg/k8s/gateway.go Switches combined list errors to use errors.Join() for chainable errors.
pkg/api/handlers/sse.go Corrects comment about namespace inclusion in SSE cache keys.
pkg/agent/server.go Adjusts JSON body decoding/validation to handle chunked/empty bodies; returns JSON error payload for analyze 400s.

var combinedErr error
if len(errs) > 0 {
combinedErr = fmt.Errorf("gateway list errors: %v", errs)
combinedErr = fmt.Errorf("gateway list errors: %w", errors.Join(errs...))
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

Wrapping errors.Join(errs...) with fmt.Errorf(... %w ...) changes the exposed unwrap shape: callers can no longer type-assert the returned error to interface{ Unwrap() []error } to retrieve all constituent errors directly (the wrapper only provides Unwrap() error). If consumers need access to the full joined list, prefer returning a joined error that includes context as one of the joined elements (e.g., join a contextual error with errs...) rather than wrapping the joined error.

Suggested change
combinedErr = fmt.Errorf("gateway list errors: %w", errors.Join(errs...))
ctxErr := fmt.Errorf("gateway list errors")
combinedErr = errors.Join(append([]error{ctxErr}, errs...)...)

Copilot uses AI. Check for mistakes.
var combinedErr error
if len(errs) > 0 {
combinedErr = fmt.Errorf("httproute list errors: %v", errs)
combinedErr = fmt.Errorf("httproute list errors: %w", errors.Join(errs...))
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

Wrapping errors.Join(errs...) with fmt.Errorf(... %w ...) changes the exposed unwrap shape: callers can no longer type-assert the returned error to interface{ Unwrap() []error } to retrieve all constituent errors directly (the wrapper only provides Unwrap() error). If consumers need access to the full joined list, prefer returning a joined error that includes context as one of the joined elements (e.g., join a contextual error with errs...) rather than wrapping the joined error.

Suggested change
combinedErr = fmt.Errorf("httproute list errors: %w", errors.Join(errs...))
contextErr := fmt.Errorf("httproute list errors")
combinedErr = errors.Join(append([]error{contextErr}, errs...)...)

Copilot uses AI. Check for mistakes.
if r.Body != nil && r.ContentLength != 0 {
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
if r.Body != nil {
if err := json.NewDecoder(r.Body).Decode(&body); err != nil && err != io.EOF {
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

This 400 response encodes a JSON body but does not set Content-Type: application/json (unlike the updated /predictions/analyze path). To keep error responses consistent and easier for clients to parse, set the JSON content type header before writing the status code here as well.

Suggested change
if err := json.NewDecoder(r.Body).Decode(&body); err != nil && err != io.EOF {
if err := json.NewDecoder(r.Body).Decode(&body); err != nil && err != io.EOF {
w.Header().Set("Content-Type", "application/json")

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

👋 Hey @clubanderson — thanks for opening this PR!

🤖 This project is developed exclusively using AI coding assistants.

Please do not attempt to code anything for this project manually.
All contributions should be authored using an AI coding tool such as:

This ensures consistency in code style, architecture patterns, test coverage,
and commit quality across the entire codebase.


This is an automated message.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

Thank you for your contribution! Your PR has been merged.

Check out what's new:

Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey

@clubanderson
Copy link
Copy Markdown
Collaborator Author

🔄 Auto-Applying Copilot Code Review

Copilot code review found 3 code suggestion(s) and 0 general comment(s).

@copilot Please apply all of the following code review suggestions:

  • pkg/k8s/gateway.go (line 54): ctxErr := fmt.Errorf("gateway list errors") combinedErr = errors.Join(append([...
  • pkg/k8s/gateway.go (line 189): contextErr := fmt.Errorf("httproute list errors") combinedErr = errors.Join(ap...
  • pkg/agent/server.go (line 1971): if err := json.NewDecoder(r.Body).Decode(&body); err != nil && err != io.EOF { ...

Push all fixes in a single commit. Run cd web && npm run build && npm run lint before committing.


Auto-generated by copilot-review-apply workflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dco-signoff: yes Indicates the PR's author has signed the DCO. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants