Skip to content

ROSAENG-62084: refactor: platform api error enumeration - #331

Merged
openshift-merge-bot[bot] merged 7 commits into
openshift-online:mainfrom
gdbranco:fix/rosaeng-62084-platform-api-error-enumeration
Aug 13, 2026
Merged

ROSAENG-62084: refactor: platform api error enumeration#331
openshift-merge-bot[bot] merged 7 commits into
openshift-online:mainfrom
gdbranco:fix/rosaeng-62084-platform-api-error-enumeration

Conversation

@gdbranco

@gdbranco gdbranco commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Description

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)
  • CI/CD or tooling change

Testing

  • Unit tests pass (make test)
  • Integration tests pass (if applicable)
  • Manual verification completed

Checklist

  • My code follows the project's coding conventions
  • I have updated documentation as needed
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass

Summary by CodeRabbit

  • New Features

    • Added consistent JSON response handling across API endpoints.
    • Introduced standardized error codes, messages, HTTP statuses, and structured error details.
    • Added validation to reject cluster names exceeding the supported length.
    • Added clearer rate-limit responses with HTTP 429 details.
    • Added safe fallback responses for internal serialization failures.
  • Bug Fixes

    • Improved error responses for unavailable accounts, authorization failures, invalid requests, and resource conflicts.
    • Validation error messages are now concise, single-line, and easier to read.
  • Tests

    • Expanded coverage for standardized responses, validation limits, and error formatting.

…lers

Introduce APIError struct with stable code, HTTP status, and message —
defined once in errorcodes.go and referenced by both handlers. Replaces
scattered inline string literals, fixes duplicate codes (CREATE-002 used
for three different conditions, nodepool CREATE-003 shared between
conflict and failure), and adds cluster name length validation
(CLUSTERS-MGMT-CREATE-006) derived from the HyperShift namespace formula.
Introduces pkg/apierror as a shared leaf package providing APIError with
WithErrors/WithReason builder methods and a Write function that derives
reason from structured or plain errors automatically. All handlers and
middleware now use typed error vars defined in errorcodes.go — no inline
JSON, no hardcoded strings, no local message overrides. Integration test
assertions updated to reference .Code fields instead of stale literals.
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The PR adds shared JSON response helpers and structured API errors. It migrates platform handlers and middleware to centralized responses, adds cluster-name validation, injects loggers into health and info handlers, and updates validation formatting and tests.

Changes

API response and error contracts

Layer / File(s) Summary
Shared response primitives
platform-api/pkg/api/*
Adds APIError, WriteError, Write, and marshal-failure fallback handling. Tests cover response formats and helper behavior.
Centralized error definitions
platform-api/pkg/handlers/errorcodes.go, platform-api/pkg/middleware/errorcodes.go, platform-api/pkg/ratelimit/middleware.go
Defines reusable error values and shared error-writing helpers.

Endpoint migration

Layer / File(s) Summary
Handlers and middleware
platform-api/pkg/handlers/*, platform-api/pkg/middleware/*
Replaces local JSON responses with shared writers and predefined API errors. Response-write failures are logged.

Validation and verification

Layer / File(s) Summary
Validation, wiring, and tests
platform-api/pkg/clients/hyperfleetdb/convert.go, platform-api/pkg/server/server.go, platform-api/pkg/validation/field_validator.go, platform-api/pkg/handlers/*_test.go, platform-api/pkg/middleware/*_test.go, hyperfleet-operator/internal/render/nodepool_test.go
Adds cluster-name length validation, updates logger injection and error-code assertions, formats validation errors on one line, and aligns a test table.

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

Mergeability Score: 🔵 Low · up to 6e155

The refactor centralizes platform API error responses and adds redaction behavior; one path does not handle serialization failure and another can split multibyte UTF-8 input, potentially producing malformed client responses. The PR is otherwise mergeable with explicit owner awareness of these bounded correctness risks.

Possibly related PRs

Suggested reviewers: typeid

🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.12% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (10 passed)
Check name Status Explanation
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.
No-Weak-Crypto ✅ Passed The main-to-HEAD diff adds no MD5, SHA1, DES, RC4, Blowfish, ECB, or crypto implementation; changed comparisons are nil/empty/error checks, not secret or token checks.
Container-Privileges ✅ Passed The full PR diff adds no Dockerfile or container/Kubernetes manifest and no prohibited privilege fields; added “privileged” text is API authorization logic, not container privilege.
No-Sensitive-Data-In-Logs ✅ Passed The diff shows changed customer-ID logs use redact; added logs record only generic write errors, while existing unredacted logs are unchanged.
No-Hardcoded-Secrets ✅ Passed The cumulative PR diff adds no secret-like assignments, credential URLs, private keys, or base64 strings over 32 characters; the only long literal is a documented UUID example.
No-Injection-Vectors ✅ Passed The complete PR diff adds no SQL concatenation, shell or command execution, eval/exec, unsafe YAML loading, pickle.loads, or dangerouslySetInnerHTML.
Ai-Attribution ✅ Passed The PR description and all five PR commits contain no AI-tool mention or attribution trailer; no AI Co-Authored-By trailer occurs in the PR range.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the refactoring of platform API error enumeration, which is the primary change in the pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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: 4

🤖 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 `@platform-api/pkg/api/error.go`:
- Around line 45-59: Update the error response flow around the APIError envelope
and its Encode call to serialize the complete response before invoking
WriteHeader. Handle marshal/serialization failures, including unencodable
structured Errors values that bypass the error branch, and return both
serialization and post-commit write errors to the caller instead of discarding
them; only commit the HTTP status after serialization succeeds.

In `@platform-api/pkg/api/response.go`:
- Around line 18-25: Update the response-writing function around json.Marshal so
serialization failures write the centralized 500 error response before
returning, ensuring handlers do not leave the client with an empty default 200
response. Keep post-commit failures from w.Write as returned errors for logging,
and preserve the existing successful JSON response flow.

In `@platform-api/pkg/handlers/accounts.go`:
- Line 89: Remove the customer identifier fields from the success logs: in
platform-api/pkg/handlers/accounts.go:89-89, update the account-enabled log to
omit req.AccountID; in platform-api/pkg/handlers/management_cluster.go:94-94,
update the corresponding success log to omit accountID and mc.Name. Retain only
non-sensitive fields or use an approved correlation identifier.

In `@platform-api/pkg/handlers/health.go`:
- Around line 32-42: Handle and log every error returned by api.Write in
HealthHandler.Readiness and the corresponding health handler code at
platform-api/pkg/handlers/health.go lines 32-42, adding or reusing the handler
logger; also add the logger and log the api.Write error at
platform-api/pkg/handlers/info.go line 36. Do not discard these write errors,
including both readiness response paths.
🪄 Autofix

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: openshift-online/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5e360b1f-1ba8-4763-b93e-c30a8e778fdd

📥 Commits

Reviewing files that changed from the base of the PR and between f0366b5 and e0d4450.

📒 Files selected for processing (28)
  • hyperfleet-operator/internal/render/nodepool_test.go
  • platform-api/pkg/api/error.go
  • platform-api/pkg/api/error_test.go
  • platform-api/pkg/api/response.go
  • platform-api/pkg/clients/hyperfleetdb/convert.go
  • platform-api/pkg/handlers/accounts.go
  • platform-api/pkg/handlers/authz.go
  • platform-api/pkg/handlers/cluster.go
  • platform-api/pkg/handlers/cluster_test.go
  • platform-api/pkg/handlers/errorcodes.go
  • platform-api/pkg/handlers/health.go
  • platform-api/pkg/handlers/info.go
  • platform-api/pkg/handlers/info_test.go
  • platform-api/pkg/handlers/management_cluster.go
  • platform-api/pkg/handlers/nodepool.go
  • platform-api/pkg/handlers/zoa.go
  • platform-api/pkg/handlers/zoa_test.go
  • platform-api/pkg/middleware/account_check.go
  • platform-api/pkg/middleware/admin_check.go
  • platform-api/pkg/middleware/admin_check_test.go
  • platform-api/pkg/middleware/authorization.go
  • platform-api/pkg/middleware/authorization_test.go
  • platform-api/pkg/middleware/authz.go
  • platform-api/pkg/middleware/errorcodes.go
  • platform-api/pkg/middleware/privileged.go
  • platform-api/pkg/ratelimit/middleware.go
  • platform-api/pkg/ratelimit/middleware_test.go
  • platform-api/pkg/validation/field_validator.go

Comment thread platform-api/pkg/api/error.go
Comment thread platform-api/pkg/api/response.go
Comment thread platform-api/pkg/handlers/accounts.go Outdated
Comment thread platform-api/pkg/handlers/health.go Outdated
@gdbranco
gdbranco force-pushed the fix/rosaeng-62084-platform-api-error-enumeration branch from e0d4450 to 66552e2 Compare August 12, 2026 21:15
Moves APIError, WriteError, and builders (WithReason, WithErrors) from
pkg/apierror into pkg/api alongside the new api.Write for success
responses. All handlers now route every response — success, no-content,
and error — through these two functions instead of open-coded
w.Header/w.WriteHeader/json.Encode triples.

api.Write marshals to a buffer before committing headers so a marshal
failure can still return a 500; write errors after headers are committed
are returned to the caller for logging rather than silently discarded.
@gdbranco
gdbranco force-pushed the fix/rosaeng-62084-platform-api-error-enumeration branch from 66552e2 to 0da7ade Compare August 12, 2026 21:17
…leware

WriteError now uses marshal-before-commit and returns error. All
writeAPIError and writeError wrappers accept a *slog.Logger and log
failures. InfoHandler and HealthHandler gain logger fields, removing
the last TODO stubs.

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

🤖 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 `@platform-api/pkg/api/errorcodes.go`:
- Around line 19-23: Handle the error returned by json.Marshal when initializing
fallbackBody in the error-code initialization flow. Ensure a marshal failure
cannot leave fallbackBody nil: either propagate the initialization error or fail
fast, while preserving the existing fallback payload for successful marshaling.

In `@platform-api/pkg/handlers/redact.go`:
- Around line 14-15: Update redact to calculate the midpoint and slice boundary
using runes rather than byte length, ensuring the returned string remains valid
UTF-8 for multibyte characters. Add a regression case in redact tests covering a
value such as “aé” and verify the expected redacted output.
🪄 Autofix

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: openshift-online/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: be9eed81-a175-4f10-80bc-6590e506fce8

📥 Commits

Reviewing files that changed from the base of the PR and between e871157 and 6e1553f.

📒 Files selected for processing (7)
  • platform-api/pkg/api/error.go
  • platform-api/pkg/api/errorcodes.go
  • platform-api/pkg/api/response.go
  • platform-api/pkg/handlers/accounts.go
  • platform-api/pkg/handlers/management_cluster.go
  • platform-api/pkg/handlers/redact.go
  • platform-api/pkg/handlers/redact_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • platform-api/pkg/api/response.go
  • platform-api/pkg/handlers/management_cluster.go
  • platform-api/pkg/handlers/accounts.go
  • platform-api/pkg/api/error.go

Comment thread platform-api/pkg/api/errorcodes.go Outdated
Comment thread platform-api/pkg/handlers/redact.go Outdated
…action

- WriteError returns error and writes fallback 500 on marshal failure
- Write sends centralized 500 via WriteError when json.Marshal fails
- fallbackBody pre-computed in errorcodes.go init() to avoid init ordering bug
- Redact first half of customer identifiers in success logs
@gdbranco
gdbranco force-pushed the fix/rosaeng-62084-platform-api-error-enumeration branch from 6e1553f to a4c76f4 Compare August 12, 2026 21:56
@cdoan1 cdoan1 changed the title ROSAENG-62084 | refactor: platform api error enumeration ROSAENG-62084: refactor: platform api error enumeration Aug 12, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Aug 12, 2026
@openshift-ci-robot

openshift-ci-robot commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

@gdbranco: This pull request references ROSAENG-62084 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 epic to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Description

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)
  • CI/CD or tooling change

Testing

  • Unit tests pass (make test)
  • Integration tests pass (if applicable)
  • Manual verification completed

Checklist

  • My code follows the project's coding conventions
  • I have updated documentation as needed
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass

Summary by CodeRabbit

  • New Features

  • Added consistent JSON response handling across API endpoints.

  • Introduced standardized error codes, messages, HTTP statuses, and structured error details.

  • Added validation to reject cluster names exceeding the supported length.

  • Added clearer rate-limit responses with HTTP 429 details.

  • Added safe fallback responses for internal serialization failures.

  • Bug Fixes

  • Improved error responses for unavailable accounts, authorization failures, invalid requests, and resource conflicts.

  • Validation error messages are now concise, single-line, and easier to read.

  • Tests

  • Expanded coverage for standardized responses, validation limits, and error formatting.

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.

@cdoan1

cdoan1 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

/approve
/test on-demand-e2e

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 12, 2026
@cdoan1

cdoan1 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 12, 2026
@gdbranco

Copy link
Copy Markdown
Contributor Author

/retest

Assert status code explicitly and update code field from "429" to
"RATE-LIMIT-001" to match the typed error definition.
@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Aug 12, 2026
@gdbranco

Copy link
Copy Markdown
Contributor Author

/test on-demand-e2e

…r codes

Replace stale legacy strings with the actual typed codes:
- "missing-target-cluster" → ZOA-CREATE-003
- "missing-jira"           → ZOA-CREATE-004
- "invalid-jira"           → ZOA-CREATE-005
- "invalid-params"         → ZOA-CREATE-006
- "write-cooldown"         → ZOA-CREATE-007
- "account-exists"         → ACCOUNTS-MGMT-CREATE-004
@gdbranco

Copy link
Copy Markdown
Contributor Author

/test on-demand-e2e

@cdoan1

cdoan1 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

@gdbranco I verified the e2e locally

@cdoan1

cdoan1 commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 13, 2026
@openshift-ci

openshift-ci Bot commented Aug 13, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cdoan1, gdbranco

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

@openshift-merge-bot
openshift-merge-bot Bot merged commit 9b4e391 into openshift-online:main Aug 13, 2026
14 checks passed
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. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants