Skip to content

fix(api): surface cross-DB invariant breakages as 4xx, not 500#101

Merged
ccomb merged 2 commits into
mainfrom
fix/api-error-status-contract
May 28, 2026
Merged

fix(api): surface cross-DB invariant breakages as 4xx, not 500#101
ccomb merged 2 commits into
mainfrom
fix/api-error-status-contract

Conversation

@ccomb

@ccomb ccomb commented May 28, 2026

Copy link
Copy Markdown
Owner

What

The ServiceError → HTTP status mapping had two constructors falling through to HTTP 500: InvalidUUID and FlowNotFound. Both are client-supplied invariant breakages, so they now return 400 and 404 respectively — no ServiceError maps to 5xx anymore.

Also in this slice:

  • A pure serviceErrorToServerError mapping, so the ServiceError → HTTP status contract is unit-testable without booting a server (RoutesSpec now has a platform-independent regression guard).
  • validateUUID returns the parsed UUID instead of the original text, removing a double-parse (and a now-unreachable error branch) in withValidatedFlow.
  • Drive-by cleanup from the same sweep: drop unused Data.Validation helpers (fromEither, success), a comment fix in API.Types, an exhaustiveness comment in Method.Mapping, and whitespace in DatabaseHandlers.

Why

These were meant to land with the #87 behavior-preserving cleanup sweep but were left uncommitted in the working tree. This is the behavior-changing part (status codes), so it's split out into its own PR.

Tests

cabal test → 1114 examples, 0 failures. New CrossDBLinkingStats Semigroup/Monoid tests and the serviceErrorToServerError status-contract tests included.

ccomb added 2 commits May 28, 2026 23:17
The supply-chain and aggregate endpoints returned 500 when a process id
was parseable but absent from the matrix index, or when a matrix solve
failed. Those are client-submitted invariant breakages, so they now map
to 422 like the rest of the cross-DB pipeline.

Introduces a pure serviceErrorToServerError mapping so the status
contract is unit-testable without booting a server, makes validateUUID
return the parsed UUID (callers no longer re-parse), and states the
expected activity_uuid_product_uuid format in the InvalidProcessId body.

These changes were meant to ship with the #87 cleanup sweep but were
left uncommitted.
The [Unreleased] entry described work not in this PR: MatrixError already
mapped to 422 on main, the fixed-string "Invalid ProcessId format" bodies are
still present, and the OpenAPI schema alignment lives in earlier commits. Trim
it to what this PR actually changes — InvalidUUID 500->400, FlowNotFound
500->404.

Also drop the stale "Translate a Service-level error" Haddock block left
stacked above serviceErrorToServerError's own doc comment.
@ccomb ccomb merged commit 8239545 into main May 28, 2026
6 checks passed
@ccomb ccomb deleted the fix/api-error-status-contract branch May 28, 2026 21:40
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.

1 participant