feat(api): wire ConduitError into the API error boundary#2527
Merged
Conversation
Step 2 of the structured-error rollout: the ConduitError foundation now reaches the API. When an error returned to a gRPC/HTTP handler carries a *ConduitError (anywhere in its chain), status.go emits its gRPC category plus an additive google.rpc.ErrorInfo detail carrying the stable reason, configPath, suggestion, and fix — so an API/MCP/UI consumer gets a machine-actionable error. This is a single integration point (conduitErrorStatus, checked at the top of PipelineError/ConnectorError/ProcessorError/PluginError). It is purely additive: any error that is NOT a ConduitError falls through to the existing sentinel->code mapping, byte-for-byte unchanged (existing tests still pass). Boundaries get migrated to emit ConduitError codes incrementally from here. Tests: a wrapped ConduitError yields the right code + ErrorInfo detail (reason, configPath, suggestion); a sentinel error maps exactly as before. Design: docs/design-documents/20260705-conduit-error-and-structured-output.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 5, 2026
devarismeroxa
added a commit
that referenced
this pull request
Jul 6, 2026
…peline, connector, orchestrator (#2538) Continues the structured-error rollout (steps 2-4 covered not-found errors in #2527-#2532) by migrating the non-not-found sentinels used to guard pipeline lifecycle and mutation preconditions: - pipeline.running / pipeline.not_running (codes.FailedPrecondition): ErrPipelineRunning / ErrPipelineNotRunning, wrapped at their clean control-plane raise sites in pkg/lifecycle/service.go (Start/Stop) and pkg/orchestrator/{pipelines,connectors,processors}.go (Update/Delete/Create guards). - pipeline.name_already_exists (codes.AlreadyExists) / pipeline.name_missing (codes.InvalidArgument): pkg/pipeline/service.go Update and validatePipeline (the latter joined via cerrors.Join, same pattern as pkg/provisioning/config/validate.go). - connector.running (codes.FailedPrecondition): the single choke point, Instance.Connector in pkg/connector/instance.go. - connector.invalid_type (codes.InvalidArgument): the user-facing check in connector.Service.Create. - orchestrator.invalid_processor_parent_type (codes.InvalidArgument), orchestrator.pipeline_has_{processors,connectors}_attached, orchestrator.connector_has_processors_attached, orchestrator.immutable_provisioned_by_config (all codes.FailedPrecondition): new pkg/orchestrator/codes.go, wrapped at every raise site in the orchestrator package. Every sentinel stays in the error chain via conduiterr.Wrap (invariant comment at each site); existing errors.Is checks are preserved, though tests that previously asserted strict `is.Equal(err, sentinel)` identity had to be updated to errors.Is + a ConduitError code/suggestion check, since wrapping necessarily changes the concrete error value (documented in the PR). Deferred (reported, not migrated, to keep blast radius tight): the lifecycle-poc (PipelineArchV2 preview) mirror of ErrPipelineRunning/ ErrPipelineNotRunning; the internal runPipeline tomb-alive defensive check; and three defensive/unreachable ErrInvalidConnectorType switch defaults (SetState, store.decode, Instance.Connector) guarding already-validated data. Design: docs/design-documents/20260705-conduit-error-and-structured-output.md Claude-Session: https://claude.ai/code/session_01Tapg9dLWXKMZJoL65R24vd Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step 2 of the structured-error rollout (design:
docs/design-documents/20260705-conduit-error-and-structured-output.md; foundation landed in #2524).The
ConduitErrorfoundation now reaches the API. When an error returned to a handler carries a*ConduitErroranywhere in its chain,status.goemits its gRPC category plus an additivegoogle.rpc.ErrorInfodetail (stable reason, configPath, suggestion, fix) — so an API/MCP/UI consumer gets a machine-actionable error.Purely additive
A single integration point (
conduitErrorStatus, checked at the top ofPipelineError/ConnectorError/ProcessorError/PluginError). Any error that is not a ConduitError falls through to the existing sentinel→code mapping, byte-for-byte unchanged — all existing tests pass. Individual error sources get migrated to emit ConduitError codes incrementally from here (step 3).Tests
ConduitError→ correct gRPC code +ErrorInfodetail (reason/configPath/suggestion). Proves the compat path end-to-end at the boundary.Tier 2 (API boundary, additive, no behavior change for existing errors). Advances #2451 (error codes in the API).
🤖 Generated with Claude Code