Skip to content

TRT-2771: Return HTTP 400 for invalid filter fields instead of 500#3739

Open
mstaeble wants to merge 3 commits into
openshift:mainfrom
mstaeble:trt-2771-filter-validation
Open

TRT-2771: Return HTTP 400 for invalid filter fields instead of 500#3739
mstaeble wants to merge 3 commits into
openshift:mainfrom
mstaeble:trt-2771-filter-validation

Conversation

@mstaeble

@mstaeble mstaeble commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Catches Postgres SQLSTATE 42703 (undefined column) and BigQuery HTTP 400 errors at the HTTP response boundary, returning 400 instead of 500
  • Fixes FilterOptionsFromRequest and ExtractFilters error responses from 500 to 400 across all handlers
  • Error details are logged server-side but not leaked to the client
  • Preserves error type chain through errors.Join so pgconn.PgError is detectable by errors.As at the boundary

Context

API clients sending filter parameters with unrecognized column names (e.g., columnField: "component" on /api/tests) caused database errors surfaced as HTTP 500 responses. The database already validates column names, so we catch those errors at the boundary layer rather than maintaining a parallel field list.

Follow-up

Some pkg/api functions (e.g., PrintTestsJSONFromDB) write HTTP responses directly rather than returning errors to the sippyserver handler layer. This creates two parallel error response paths (RespondWithError vs failureResponseWithError). Unifying this by having all pkg/api functions return errors and letting sippyserver handle all HTTP responses is left for a follow-up refactor.

Test plan

  • make lint passes
  • make test passes (14924 Go tests, 19 JS tests, 54 Python tests)
  • Manual: invalid filter field returns 400
  • Manual: valid filter field returns 200

Manual test evidence (against staging DB)

Invalid filter field (component) on /api/tests returns 400:

$ curl -s 'localhost:9090/api/tests?release=4.18&filter={"items":[{"columnField":"component","operatorValue":"equals","value":"test"}]}'
{"code":400,"message":"error building test report"}

Valid filter field (name) on /api/tests returns 200:

$ curl -s 'localhost:9090/api/tests?release=4.18&filter={"items":[{"columnField":"name","operatorValue":"contains","value":"openshift-tests"}]}&limit=1' | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'{len(d)} test(s) returned')"
1 test(s) returned

Invalid filter field (timestamp) on /api/jobs returns 400:

$ curl -s 'localhost:9090/api/jobs?release=4.18&filter={"items":[{"columnField":"timestamp","operatorValue":"equals","value":"test"}]}'
{"code":400,"message":"error building job report"}

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved API error handling so invalid request/filter parameters now return 400 Bad Request instead of server errors across multiple report and query endpoints.
    • Standardized JSON error responses and messages for job, test, release, and pull request reporting, including clearer “build report” failures.
    • Added consistent bad-request classification for PostgreSQL and BigQuery-style errors.
  • Tests
    • Added unit tests covering bad-request detection for PostgreSQL and Google API error variants.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@openshift-ci

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci-robot

openshift-ci-robot commented Jul 7, 2026

Copy link
Copy Markdown

@mstaeble: This pull request references TRT-2771 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

@coderabbitai ignore

Summary

  • Catches Postgres SQLSTATE 42703 (undefined column) and BigQuery HTTP 400 errors at the HTTP response boundary, returning 400 instead of 500
  • Fixes FilterOptionsFromRequest and ExtractFilters error responses from 500 to 400 across all handlers
  • Error details are logged server-side but not leaked to the client

Context

API clients sending filter parameters with unrecognized column names (e.g., columnField: "component" on /api/tests) caused database errors surfaced as HTTP 500 responses. The database already validates column names, so we catch those errors at the boundary layer rather than maintaining a parallel field list.

Follow-up

Some pkg/api functions (e.g., PrintTestsJSONFromDB) write HTTP responses directly rather than returning errors to the sippyserver handler layer. This creates two parallel error response paths (RespondWithError vs failureResponseWithError). Unifying this by having all pkg/api functions return errors and letting sippyserver handle all HTTP responses is left for a follow-up refactor.

Test plan

  • make lint passes
  • make test passes (14936 Go tests, 19 JS tests, 54 Python tests)
  • Manual: start sippy serve, send request with invalid filter field, verify 400 response
  • Manual: send request with valid filter field, verify 200 response

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 7, 2026
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 7, 2026
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@openshift-ci-robot: Noted. Since this PR includes @coderabbitai ignore, CodeRabbit will not perform an automated review of this pull request. No action needed on my end regarding the Jira target version warning.

@mstaeble mstaeble force-pushed the trt-2771-filter-validation branch 4 times, most recently from 762ecc8 to 44414e9 Compare July 7, 2026 14:43
@mstaeble

mstaeble commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@mstaeble, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 6 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 7efcf39c-e847-4a23-8bf3-70f5f72330f5

📥 Commits

Reviewing files that changed from the base of the PR and between f952ead and bb341d0.

📒 Files selected for processing (1)
  • pkg/api/api_test.go

Walkthrough

This PR adds shared error-classification helpers and updates API and server handlers to return HTTP 400 for request/parsing failures while routing other errors through a common JSON error response. It also promotes pgconn to a direct dependency and adjusts error wrapping and aggregation in test-report code.

Changes

Error handling and request classification

Layer / File(s) Summary
Shared helpers and dependency update
go.mod, pkg/api/api.go
Promotes pgconn to a direct dependency and adds IsBadRequestError plus RespondWithError for typed bad-request detection and JSON error responses.
API report handlers and tests support
pkg/api/jobs.go, pkg/api/releases.go, pkg/api/tests.go, pkg/api/api_test.go
Updates report handlers to return 400 for parsing failures and use the shared error responder for backend failures; also changes error joining/wrapping behavior and adds unit coverage for bad-request classification.
Server handler error routing
pkg/sippyserver/server.go
Adds a shared failure helper and applies it across multiple JSON handlers so parsing failures return 400 and classified backend errors reuse the shared error response path.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Handler
  participant IsBadRequestError
  participant RespondWithError
  participant failureResponseWithError
  participant ResponseWriter

  Client->>Handler: HTTP request
  Handler->>Handler: parse request / build filters / query data
  alt request parsing failure
    Handler->>ResponseWriter: write 400 JSON error
  else backend error
    Handler->>RespondWithError: API handlers use shared responder
    RespondWithError->>IsBadRequestError: classify err
    IsBadRequestError-->>RespondWithError: true or false
    RespondWithError->>ResponseWriter: write 400 or 500 JSON error
    Handler->>failureResponseWithError: server handlers use shared failure helper
    failureResponseWithError->>IsBadRequestError: classify err
    IsBadRequestError-->>failureResponseWithError: true or false
    failureResponseWithError->>ResponseWriter: write 400 or 500 JSON error
  end
  ResponseWriter-->>Client: HTTP response
Loading
🚥 Pre-merge checks | ✅ 20 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Coverage For New Features ⚠️ Warning Only IsBadRequestError has unit tests; the new 400 response paths in handlers/helper lack regression coverage. Add tests for invalid filter-field requests hitting PrintJobsReportFromDB/PrintTestsJSON/PrintPullRequestsReport and assert HTTP 400 JSON responses.
✅ Passed checks (20 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: invalid filter fields now return HTTP 400 instead of 500.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Go Error Handling ✅ Passed No new ignored errors, panics, or unsafe nil dereferences; added handlers classify and log errors while preserving context via wrapping/joining.
Sql Injection Prevention ✅ Passed Only error classification/HTTP response helpers changed; no SQL query construction, concatenation, or parameter handling was added or modified.
Excessive Css In React Should Use Styles ✅ Passed PR only changes Go files in pkg/api; no React/JSX/CSS or inline style objects were introduced.
Single Responsibility And Clear Naming ✅ Passed The added helpers are narrowly scoped and clearly named; no new broad structs, vague methods, or muddled package boundaries were introduced.
Feature Documentation ✅ Passed PASS: The only feature doc is job-analysis-symptoms.md, and this PR’s API/filter error changes don’t affect its symptom/label/re-evaluate scope.
Stable And Deterministic Test Names ✅ Passed No Ginkgo titles were added; the new test uses static t.Run names only, with no dynamic values.
Test Structure And Quality ✅ Passed PASS: The only added test is a simple table-driven unit test, not Ginkgo, and it has no cluster setup, waits, or cleanup concerns.
Microshift Test Compatibility ✅ Passed Changed files add only a standard Go unit test; no new Ginkgo e2e tests or unsupported MicroShift APIs/features were introduced.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the only new test is a unit test of IsBadRequestError with no cluster/topology assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed Only HTTP error-handling code in pkg/api changed; no manifests, controllers, or scheduling constraints were added.
Ote Binary Stdout Contract ✅ Passed Touched files add only HTTP response writes and stderr logging; no main/init/TestMain/BeforeSuite or klog/stdout writes were introduced.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The PR adds only a standard table-driven unit test in pkg/api/api_test.go; it uses testing, no Ginkgo e2e constructs, IPv4 literals, or external network calls.
No-Weak-Crypto ✅ Passed Modified files only add error-handling/test code; searched changed files and found no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or secret-compare usage.
Container-Privileges ✅ Passed No container/K8s manifests were changed; the PR diff is only Go code, and no privilege-related fields appear in the modified files.
No-Sensitive-Data-In-Logs ✅ Passed New logs only record generic errors and operational fields; no passwords, tokens, PII, hostnames, or customer data are logged.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with 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.

❤️ Share

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

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/sippyserver/server.go (1)

549-568: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use failureResponseWithError here

api.ListPayloadJobRuns can fail on the DB query as well as filter parsing, so this path should not always return 400 or echo err.Error(). That keeps client errors as 400 while surfacing internal failures as 500 without leaking DB details.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/sippyserver/server.go` around lines 549 - 568, jsonListPayloadJobRuns
should use failureResponseWithError instead of always returning a 400 and
concatenating err.Error(), because api.ListPayloadJobRuns can fail for internal
DB reasons as well as bad request filters. Keep FilterOptionsFromRequest
handling for request parsing errors, but for the api.ListPayloadJobRuns call
switch to failureResponseWithError so client-side issues still map to 400 while
server/DB failures surface as 500 without leaking details.
🧹 Nitpick comments (2)
pkg/api/api.go (2)

28-52: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing unit tests for new exported helpers.

RespondWithError and IsBadRequestError are new exported functions with branching logic (pg error code vs. googleapi code) but no accompanying test file is included in this cohort. As per coding guidelines, **/*.{go,tsx,jsx}: "new Go functions and methods need unit tests". These are also pure/logic functions with no external client calls, so per the testing learning they should be straightforward to test directly without mocking storage clients.

Could you confirm whether tests exist elsewhere in the stack, or add table-driven tests covering: nil err, generic error, wrapped *pgconn.PgError with code 42703, wrapped *pgconn.PgError with a different code, and wrapped *googleapi.Error with/without 400?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/api.go` around lines 28 - 52, Add unit tests for the new exported
helpers in api.go. Cover RespondWithError and IsBadRequestError with
table-driven cases for nil error, generic error, wrapped pgconn.PgError with
code 42703 and a non-matching code, and wrapped googleapi.Error with 400 and a
non-400 code. Use the function names RespondWithError and IsBadRequestError to
locate the logic, and verify the HTTP status selection in RespondWithError
matches the bad-request detection.

Source: Coding guidelines


42-52: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Overly broad googleapi 400 classification risks masking real server bugs.

The Postgres branch narrowly targets SQLSTATE 42703 (undefined column), but the googleapi branch treats any Code == http.StatusBadRequest as a client error. BigQuery returns 400 for many distinct reasons beyond invalid filter columns, e.g. malformed generated SQL, type mismatches, or invalid query arguments. If a server-side bug generates an invalid BigQuery query, it will now surface to clients as a generic 400 "bad request" instead of a 500, hiding real defects from alerting/monitoring and misleading callers into thinking their input was invalid.

Consider narrowing the googleapi check to the specific reason (e.g. invalidQuery combined with a message pattern for unknown columns) rather than matching on the HTTP status alone, mirroring the specificity used for the Postgres case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/api.go` around lines 42 - 52, The googleapi branch in
IsBadRequestError is too broad because it maps every googleapi.Error with HTTP
400 to a client error. Narrow this check to the specific BigQuery error
condition that indicates an unknown column, using the googleapi.Error details
(such as reason and message) instead of status code alone, and keep the Postgres
pgErr/pgUndefinedColumn logic unchanged so only genuinely invalid input is
classified as bad request.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/api/releases.go`:
- Around line 332-336: The error response in PrintReleasesReport uses copied
job-run wording, so update the message built after
filter.FilterOptionsFromRequest to reference the releases report instead of “job
run report.” Keep the existing BadRequest handling, but change the text in the
RespondWithJSON payload to match the releases-report context in
PrintReleasesReport and avoid reusing PrintJobsReportFromDB phrasing.

In `@pkg/api/tests.go`:
- Line 6: Replace the remaining pkgerrors.Wrap usages in tests.go with stdlib
error wrapping using fmt.Errorf and %w, matching the repo guideline and
preserving the error chain. Update the affected wrapping sites in the test
helper/code paths that currently use pkgerrors.Wrap, keep the existing context
text, and if pkgerrors is no longer referenced afterward remove its import from
the file. Use the existing errors import and the relevant helper/function names
around the current wrap sites to locate each change.

In `@pkg/sippyserver/server.go`:
- Around line 454-461: The logic in failureResponseWithError duplicates
api.RespondWithError, including bad-request classification, error logging, and
JSON response construction. Update failureResponseWithError to delegate to
api.RespondWithError instead of re-implementing the behavior, using the existing
failureResponseWithError and api.RespondWithError symbols to keep response
handling centralized and avoid drift.

---

Outside diff comments:
In `@pkg/sippyserver/server.go`:
- Around line 549-568: jsonListPayloadJobRuns should use
failureResponseWithError instead of always returning a 400 and concatenating
err.Error(), because api.ListPayloadJobRuns can fail for internal DB reasons as
well as bad request filters. Keep FilterOptionsFromRequest handling for request
parsing errors, but for the api.ListPayloadJobRuns call switch to
failureResponseWithError so client-side issues still map to 400 while server/DB
failures surface as 500 without leaking details.

---

Nitpick comments:
In `@pkg/api/api.go`:
- Around line 28-52: Add unit tests for the new exported helpers in api.go.
Cover RespondWithError and IsBadRequestError with table-driven cases for nil
error, generic error, wrapped pgconn.PgError with code 42703 and a non-matching
code, and wrapped googleapi.Error with 400 and a non-400 code. Use the function
names RespondWithError and IsBadRequestError to locate the logic, and verify the
HTTP status selection in RespondWithError matches the bad-request detection.
- Around line 42-52: The googleapi branch in IsBadRequestError is too broad
because it maps every googleapi.Error with HTTP 400 to a client error. Narrow
this check to the specific BigQuery error condition that indicates an unknown
column, using the googleapi.Error details (such as reason and message) instead
of status code alone, and keep the Postgres pgErr/pgUndefinedColumn logic
unchanged so only genuinely invalid input is classified as bad request.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 0c6db7fe-41eb-4672-97f0-4eaee6e70481

📥 Commits

Reviewing files that changed from the base of the PR and between be8d0a0 and 44414e9.

📒 Files selected for processing (6)
  • go.mod
  • pkg/api/api.go
  • pkg/api/jobs.go
  • pkg/api/releases.go
  • pkg/api/tests.go
  • pkg/sippyserver/server.go

Comment thread pkg/api/releases.go
Comment thread pkg/api/tests.go
Comment thread pkg/sippyserver/server.go
@mstaeble mstaeble force-pushed the trt-2771-filter-validation branch from 44414e9 to 906e4a2 Compare July 7, 2026 15:10
API clients sending filter parameters with unrecognized column names
caused database errors (Postgres SQLSTATE 42703, BigQuery HTTP 400)
surfaced as HTTP 500 responses.

This change catches those database errors at the HTTP response boundary
and returns 400 instead of 500. Error details are logged server-side
but not leaked to the client.

Key changes:
- Add IsBadRequestError() in pkg/api that detects Postgres
  undefined-column errors (SQLSTATE 42703) and BigQuery 400 errors
- Add RespondWithError (pkg/api) and failureResponseWithError
  (pkg/sippyserver) that use IsBadRequestError to select 400 vs 500,
  log the full error server-side, and send only a generic message
- Fix FilterOptionsFromRequest and ExtractFilters error responses
  from 500 to 400 across all handlers
- Preserve error type chain through errors.Join in tests.go so
  pgconn.PgError is detectable by errors.As at the boundary

Note: some pkg/api functions write HTTP responses directly rather than
returning errors to the sippyserver handler layer. This creates two
parallel error response paths (RespondWithError vs
failureResponseWithError). Unifying this is left for a follow-up
refactor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mstaeble mstaeble force-pushed the trt-2771-filter-validation branch from 906e4a2 to f0f1d38 Compare July 7, 2026 23:22
@openshift-ci openshift-ci Bot added the ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review label Jul 8, 2026
@mstaeble mstaeble marked this pull request as ready for review July 8, 2026 01:33
@mstaeble mstaeble changed the title [WIP] TRT-2771: Return HTTP 400 for invalid filter fields instead of 500 TRT-2771: Return HTTP 400 for invalid filter fields instead of 500 Jul 8, 2026
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 8, 2026
@openshift-ci openshift-ci Bot requested review from dgoodwin and petr-muller July 8, 2026 01:33
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

@neisw

neisw commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added lgtm Indicates that a PR is ready to be merged. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Jul 8, 2026

@sosiouxme sosiouxme left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Much better this way, thanks
/lgtm
/hold
in case you want to address the nit first

Comment thread pkg/api/api.go Outdated
Comment thread pkg/api/releases.go
@openshift-ci openshift-ci Bot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 8, 2026
@openshift-ci

openshift-ci Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: mstaeble, neisw, sosiouxme

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

The pull request process is described 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

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Jul 8, 2026
@openshift-ci

openshift-ci Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

New changes are detected. LGTM label has been removed.

@mstaeble

mstaeble commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

/hold cancel

Addressed nit from review.

@openshift-ci openshift-ci Bot removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 8, 2026

@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.

🧹 Nitpick comments (1)
pkg/api/api_test.go (1)

37-41: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider adding an errors.Join test case.

The PR description states handlers use errors.Join to preserve the error type chain so pgconn.PgError can still be detected with errors.As. errors.Join produces an error implementing Unwrap() []error, which errors.As traverses via a different code path than the Unwrap() error chain tested by the fmt.Errorf("...: %w", ...) cases. Adding a case like the one below would verify this end-to-end behavior directly.

♻️ Suggested additional test case
 		{
 			name: "wrapped googleapi 400 invalidQuery",
 			err: fmt.Errorf("bq failed: %w", &googleapi.Error{
 				Code:   400,
 				Errors: []googleapi.ErrorItem{{Reason: bqInvalidQuery}},
 			}),
 			want: true,
 		},
+		{
+			name: "errors.Join wrapped pg undefined column",
+			err:  errors.Join(fmt.Errorf("context"), &pgconn.PgError{Code: "42703"}),
+			want: true,
+		},
 	}

Note: this would require adding "errors" to the import block.

Also applies to: 71-78

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/api/api_test.go` around lines 37 - 41, Add an `errors.Join`-based test
case in `pkg/api/api_test.go` alongside the existing `Test...` cases that
exercise `errors.As` detection for `pgconn.PgError`, so the suite covers the
`Unwrap() []error` path as well as the current `fmt.Errorf("%w")` wrapping;
update the import block to include `errors`, and mirror the existing
wrapped-pg-error assertions in the relevant table entries referenced by the test
helper names.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/api/api_test.go`:
- Around line 37-41: Add an `errors.Join`-based test case in
`pkg/api/api_test.go` alongside the existing `Test...` cases that exercise
`errors.As` detection for `pgconn.PgError`, so the suite covers the `Unwrap()
[]error` path as well as the current `fmt.Errorf("%w")` wrapping; update the
import block to include `errors`, and mirror the existing wrapped-pg-error
assertions in the relevant table entries referenced by the test helper names.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: f37edb4e-1722-447c-9e8e-31ad27ea54d2

📥 Commits

Reviewing files that changed from the base of the PR and between 44414e9 and f952ead.

📒 Files selected for processing (7)
  • go.mod
  • pkg/api/api.go
  • pkg/api/api_test.go
  • pkg/api/jobs.go
  • pkg/api/releases.go
  • pkg/api/tests.go
  • pkg/sippyserver/server.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • pkg/api/releases.go
  • pkg/api/api.go
  • pkg/api/tests.go
  • pkg/api/jobs.go
  • go.mod
  • pkg/sippyserver/server.go

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

1 similar comment
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e

@openshift-ci

openshift-ci Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@mstaeble: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. ready-for-human-review Indicates a PR has been reviewed by automated tools and is ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants