Skip to content

Enhance error handling and introduce new error types#2573

Merged
Thushani-Jayasekera merged 8 commits into
wso2:mainfrom
Thushani-Jayasekera:err_resp_fix
Jul 12, 2026
Merged

Enhance error handling and introduce new error types#2573
Thushani-Jayasekera merged 8 commits into
wso2:mainfrom
Thushani-Jayasekera:err_resp_fix

Conversation

@Thushani-Jayasekera

Copy link
Copy Markdown
Contributor

This commit adds new error types for WebSub and WebBroker APIs, as well as HMAC secret management, to improve error categorization and handling. It also implements a new Is method for the Error type to allow comparison based on catalog codes rather than pointer identity. Additionally, the FromError and LogAndWrite functions are introduced to streamline error logging and response generation. Various API handlers have been updated to utilize a centralized error handling approach, enhancing maintainability and clarity across the codebase.

This commit adds new error types for WebSub and WebBroker APIs, as well as HMAC secret management, to improve error categorization and handling. It also implements a new `Is` method for the `Error` type to allow comparison based on catalog codes rather than pointer identity. Additionally, the `FromError` and `LogAndWrite` functions are introduced to streamline error logging and response generation. Various API handlers have been updated to utilize a centralized error handling approach, enhancing maintainability and clarity across the codebase.
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

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

Next review available in: 34 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8fea9ff8-9aae-4eee-9ae7-fcf7fdc2071b

📥 Commits

Reviewing files that changed from the base of the PR and between 9c8bf78 and 9799f06.

📒 Files selected for processing (13)
  • platform-api/internal/repository/llm.go
  • platform-api/internal/repository/subscription_repository.go
  • platform-api/internal/service/api.go
  • platform-api/internal/service/api_secret_integration_test.go
  • platform-api/internal/service/api_test.go
  • platform-api/internal/service/llm.go
  • platform-api/internal/service/llm_deployment.go
  • platform-api/internal/service/llm_provider_template_test.go
  • platform-api/internal/service/llm_test.go
  • platform-api/internal/service/mcp.go
  • platform-api/internal/service/secret_service.go
  • platform-api/internal/service/secret_service_test.go
  • platform-api/plugins/eventgateway/service/websub_api_hmac_secret.go
📝 Walkthrough

Walkthrough

This PR replaces legacy error sentinels with typed apperror catalog errors, adds centralized matching and HTTP response helpers, and updates handlers, services, repositories, webhooks, middleware, eventgateway code, DTOs, API documentation, and tests.

Changes

Apperror foundation

Layer / File(s) Summary
Catalog, matching, and response helpers
platform-api/internal/apperror/*
Adds code-based errors.Is matching, WebSub/WebBroker/HMAC catalog entries, FromError, and LogAndWrite.
Shared routing and serialization
platform-api/internal/handler/service_error.go, platform-api/internal/middleware/error_mapper.go, platform-api/internal/dto/*, platform-api/plugins/eventgateway/handler/*
Centralizes typed-error pass-through, internal fallback wrapping, logging, tracking IDs, and HTTP response writing.

Application migration

Layer / File(s) Summary
Service, repository, and plugin errors
platform-api/internal/service/*, platform-api/internal/repository/*, platform-api/plugins/eventgateway/service/*
Replaces constants-based validation, not-found, conflict, limit, deployment, secret, subscription, LLM, MCP, WebSub, and WebBroker errors with typed catalog values.
Handlers, webhooks, and tests
platform-api/internal/handler/*, platform-api/internal/webhook/*, platform-api/plugins/eventgateway/handler/*, platform-api/**/*_test.go
Removes local sentinel switches, uses serviceError and typed matchers, and updates response and error-category assertions.
Portal API contract
platform-api/resources/portal-api.yaml
Replaces the login ErrorResponse schema with structured status, code, message, and optional tracking ID fields.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested reviewers: RakhithaRR, Tharsanan1, VirajSalaka, renuka-fernando, tharindu1st, malinthaprasan, AnuGayan, chamilaadhi, Arshardh, dushaniw, tgtshanika, tharikaGitHub, CrowleyRajapakse, hisanhunais, HiranyaKavishani, HeshanSudarshana, ashera96, pubudu538, Krishanx92, PasanT9, thivindu

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description lacks the required template sections for purpose, goals, approach, tests, security, and related details. Rewrite the PR description using the repository template and add the missing sections, especially Purpose, Goals, Approach, tests, security checks, and test environment.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: centralized error handling with new error types.
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.
✨ 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.

@Thushani-Jayasekera

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jul 10, 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 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

Caution

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

⚠️ Outside diff range comments (2)
platform-api/internal/service/subscription_plan_service.go (1)

84-89: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Replace the remaining validation fmt.Errorf returns with apperror.ValidationFailed.New(...)
CreatePlan and UpdatePlan still return plain fmt.Errorf for missing handle/name and invalid status. apperror.FromError treats non-catalog errors as Internal, so these validation failures will come back as 500s instead of 400s. platform-api/internal/service/subscription_plan_service.go:84-89, 176-177, 204

🤖 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 `@platform-api/internal/service/subscription_plan_service.go` around lines 84 -
89, Replace every validation fmt.Errorf return in CreatePlan and
UpdatePlan—including missing handle, missing name, and invalid status
checks—with apperror.ValidationFailed.New(...) while preserving the existing
validation messages, so apperror.FromError classifies these failures as
validation errors.
platform-api/internal/service/llm.go (1)

1347-1361: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

nil projectRepo (a wiring issue) is mapped to ProjectNotFound, misrepresenting an internal misconfiguration as a client 404.

Elsewhere in this same file/PR (ListByProvider, line 1428-1430) and in mcp.go's ListByProject, a nil repository dependency correctly returns a generic internal fmt.Errorf, not a typed not-found. Here it returns apperror.ProjectNotFound.New(), which will surface to clients as "project not found" (404) even though the real cause is a missing/unwired dependency — masking an operational issue as normal business traffic.

🔧 Proposed fix
 	if projectHandle != nil && *projectHandle != "" {
 		if s.projectRepo == nil {
-			return nil, apperror.ProjectNotFound.New()
+			return nil, fmt.Errorf("cannot resolve project handle: project repository unavailable")
 		}
🤖 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 `@platform-api/internal/service/llm.go` around lines 1347 - 1361, Update
LLMProxyService.List so a nil s.projectRepo returns a generic internal
fmt.Errorf consistent with ListByProvider and mcp.go's ListByProject, rather
than apperror.ProjectNotFound.New(); preserve ProjectNotFound only for missing
or mismatched projects returned by the repository.
🤖 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/internal/handler/llm_apikey.go`:
- Line 110: Update DeleteLLMProviderAPIKey to preserve typed HTTP errors by
adding an errors.As guard, matching the handling in llm_proxy_apikey.go's
DeleteAPIKey and the existing ListAPIKeys/CreateAPIKey patterns. Ensure
apperror.ArtifactNotFound, apperror.LLMProviderAPIKeyNotFound, and
apperror.LLMProviderAPIKeyForbidden are returned directly, while only
unrecognized errors are passed to serviceError.

In `@platform-api/internal/handler/secret_integration_test.go`:
- Around line 925-927: Update the error message in the test assertion checking
apperror.ValidationFailed so it names ValidationFailed instead of the stale
ErrSecretRefMissing identifier; modify the relevant assertion in the secret
integration test.

In `@platform-api/internal/service/application.go`:
- Around line 204-214: Change the empty projectHandle branch in the relevant
application service method to return apperror.ValidationFailed.New() instead of
apperror.ProjectNotFound.New(), while preserving ProjectNotFound for a nil
project returned by GetProjectByHandleAndOrgID.

In `@platform-api/internal/utils/mcp.go`:
- Around line 293-296: Update the unauthorized response handling in the MCP
initialize request to use apperror.Unauthorized.New() instead of
apperror.ValidationFailed.New(), preserving the existing user-facing and log
messages so upstream 401 authentication failures produce the standard 401
payload.

---

Outside diff comments:
In `@platform-api/internal/service/llm.go`:
- Around line 1347-1361: Update LLMProxyService.List so a nil s.projectRepo
returns a generic internal fmt.Errorf consistent with ListByProvider and
mcp.go's ListByProject, rather than apperror.ProjectNotFound.New(); preserve
ProjectNotFound only for missing or mismatched projects returned by the
repository.

In `@platform-api/internal/service/subscription_plan_service.go`:
- Around line 84-89: Replace every validation fmt.Errorf return in CreatePlan
and UpdatePlan—including missing handle, missing name, and invalid status
checks—with apperror.ValidationFailed.New(...) while preserving the existing
validation messages, so apperror.FromError classifies these failures as
validation errors.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fc6fcdb3-6593-494c-bedc-1a5a50d76348

📥 Commits

Reviewing files that changed from the base of the PR and between f2089bb and 2e54259.

📒 Files selected for processing (87)
  • platform-api/internal/apperror/apperror.go
  • platform-api/internal/apperror/apperror_test.go
  • platform-api/internal/apperror/catalog.go
  • platform-api/internal/apperror/codes.go
  • platform-api/internal/apperror/respond.go
  • platform-api/internal/constants/error.go
  • platform-api/internal/handler/api.go
  • platform-api/internal/handler/api_deployment.go
  • platform-api/internal/handler/application.go
  • platform-api/internal/handler/artifact_guard_response.go
  • platform-api/internal/handler/gateway.go
  • platform-api/internal/handler/gateway_internal.go
  • platform-api/internal/handler/llm.go
  • platform-api/internal/handler/llm_apikey.go
  • platform-api/internal/handler/llm_deployment.go
  • platform-api/internal/handler/llm_proxy_apikey.go
  • platform-api/internal/handler/mcp.go
  • platform-api/internal/handler/mcp_deployment.go
  • platform-api/internal/handler/project.go
  • platform-api/internal/handler/secret.go
  • platform-api/internal/handler/secret_integration_test.go
  • platform-api/internal/handler/service_error.go
  • platform-api/internal/handler/subscription_handler.go
  • platform-api/internal/handler/subscription_plan_handler.go
  • platform-api/internal/middleware/error_mapper.go
  • platform-api/internal/repository/custom_policy.go
  • platform-api/internal/repository/deployment.go
  • platform-api/internal/repository/llm.go
  • platform-api/internal/repository/secret.go
  • platform-api/internal/repository/secret_test.go
  • platform-api/internal/repository/subscription_repository.go
  • platform-api/internal/service/api.go
  • platform-api/internal/service/api_test.go
  • platform-api/internal/service/apikey.go
  • platform-api/internal/service/application.go
  • platform-api/internal/service/application_test.go
  • platform-api/internal/service/artifact_guard.go
  • platform-api/internal/service/artifact_import.go
  • platform-api/internal/service/artifact_import_lifecycle_test.go
  • platform-api/internal/service/artifact_import_llm_provider.go
  • platform-api/internal/service/artifact_import_llm_proxy.go
  • platform-api/internal/service/artifact_import_test.go
  • platform-api/internal/service/artifact_runtime_immutable_test.go
  • platform-api/internal/service/custom_policy_test.go
  • platform-api/internal/service/deployment.go
  • platform-api/internal/service/deployment_test.go
  • platform-api/internal/service/deployment_undeploy_guard_test.go
  • platform-api/internal/service/gateway.go
  • platform-api/internal/service/gateway_internal.go
  • platform-api/internal/service/llm.go
  • platform-api/internal/service/llm_apikey.go
  • platform-api/internal/service/llm_deployment.go
  • platform-api/internal/service/llm_provider_template_test.go
  • platform-api/internal/service/llm_proxy_apikey.go
  • platform-api/internal/service/llm_secret_validation_test.go
  • platform-api/internal/service/llm_test.go
  • platform-api/internal/service/mcp.go
  • platform-api/internal/service/mcp_deployment.go
  • platform-api/internal/service/mcp_test.go
  • platform-api/internal/service/policy_validation.go
  • platform-api/internal/service/policy_validation_test.go
  • platform-api/internal/service/secret_service.go
  • platform-api/internal/service/secret_service_test.go
  • platform-api/internal/service/subscription_plan_service.go
  • platform-api/internal/service/subscription_service.go
  • platform-api/internal/utils/handle.go
  • platform-api/internal/utils/mcp.go
  • platform-api/internal/webhook/handlers_application.go
  • platform-api/internal/webhook/handlers_subscription.go
  • platform-api/internal/webhook/receiver.go
  • platform-api/plugins/eventgateway/handler/artifact_guard_response.go
  • platform-api/plugins/eventgateway/handler/catalog_error_response.go
  • platform-api/plugins/eventgateway/handler/catalog_error_response_test.go
  • platform-api/plugins/eventgateway/handler/webbroker_api.go
  • platform-api/plugins/eventgateway/handler/webbroker_api_deployment.go
  • platform-api/plugins/eventgateway/handler/webbroker_apikey.go
  • platform-api/plugins/eventgateway/handler/websub_api.go
  • platform-api/plugins/eventgateway/handler/websub_api_deployment.go
  • platform-api/plugins/eventgateway/handler/websub_api_hmac_secret.go
  • platform-api/plugins/eventgateway/handler/websub_apikey.go
  • platform-api/plugins/eventgateway/plugin.go
  • platform-api/plugins/eventgateway/service/helpers.go
  • platform-api/plugins/eventgateway/service/webbroker_api.go
  • platform-api/plugins/eventgateway/service/webbroker_api_deployment.go
  • platform-api/plugins/eventgateway/service/websub_api.go
  • platform-api/plugins/eventgateway/service/websub_api_deployment.go
  • platform-api/plugins/eventgateway/service/websub_api_hmac_secret.go
💤 Files with no reviewable changes (3)
  • platform-api/plugins/eventgateway/handler/artifact_guard_response.go
  • platform-api/internal/handler/artifact_guard_response.go
  • platform-api/internal/constants/error.go

Comment thread platform-api/internal/handler/llm_apikey.go
Comment thread platform-api/internal/handler/secret_integration_test.go
Comment thread platform-api/internal/service/application.go
Comment thread platform-api/internal/utils/mcp.go
This commit enhances error handling across multiple services and handlers by replacing generic error messages with specific validation error types. Changes include updating error responses in the LLM provider API key deletion, project handle validation, and subscription plan creation and updates. Additionally, the MCP server initialization now returns a more descriptive unauthorized error. These improvements aim to provide clearer feedback for API consumers and streamline error management throughout the codebase.
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 10, 2026
…Internal API

This commit introduces a new InternalErrorResponse struct to standardize error responses for the Gateway Internal API. The error handling in the GatewayInternalAPIHandler has been updated to utilize this new structure, ensuring consistent error messages across various endpoints. This change enhances clarity for API consumers and improves maintainability by separating internal error representations from public API responses.
This commit updates the portal API's error response structure by replacing the generic ErrorResponse schema with a more detailed Error schema. The new schema includes specific fields for status, code, message, and trackingId, providing clearer and more consistent error messages for API consumers. Additionally, the descriptions for various error responses have been enhanced to improve clarity regarding authentication failures and server errors.

@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

🤖 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/internal/handler/gateway_internal.go`:
- Around line 116-134: Unify the client-facing authentication failure response
in the handler’s missing api-key branch and VerifyToken error branch. Keep the
existing differentiated logging, but make both paths return the exact same HTTP
401 status and dto.NewInternalErrorResponse payload, using one consistent
message such as “Invalid or expired API key.”
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 10493253-08b7-4ce7-9c7a-f1c840902809

📥 Commits

Reviewing files that changed from the base of the PR and between 891f8a7 and 9c8bf78.

📒 Files selected for processing (5)
  • platform-api/internal/dto/gateway_internal_error.go
  • platform-api/internal/handler/gateway_internal.go
  • platform-api/internal/service/artifact_import.go
  • platform-api/internal/service/artifact_import_test.go
  • platform-api/resources/portal-api.yaml
🚧 Files skipped from review as they are similar to previous changes (2)
  • platform-api/internal/service/artifact_import.go
  • platform-api/internal/service/artifact_import_test.go

Comment thread platform-api/internal/handler/gateway_internal.go
malinthaprasan
malinthaprasan previously approved these changes Jul 10, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 11, 2026
Thushani-Jayasekera and others added 2 commits July 12, 2026 09:21
…er validation failures

Updated tests to reflect changes in error handling for missing additional providers and input validation. Replaced constants with appropriate apperror types for better clarity and consistency in error responses.
@Thushani-Jayasekera
Thushani-Jayasekera merged commit fdcf60a into wso2:main Jul 12, 2026
9 checks passed
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.

3 participants