Skip to content

feat(api): return rfc 9457 problem details for errors - #180

Merged
TheMeinerLP merged 14 commits into
mainfrom
feat/problem-details
Oct 7, 2026
Merged

TheMeinerLP merged 14 commits into
mainfrom
feat/problem-details

Conversation

@TheMeinerLP

Copy link
Copy Markdown
Contributor

Summary

All error responses of the Otis API now use RFC 9457 Problem Details (application/problem+json). This prepares the upcoming player settings API (stacked PR), which needs stable error types.

  • Errors carry a stable type URI (https://otis.onelitefeather.net/problems/<slug>), title, status and, where useful, detail. Generic HTTP errors use about:blank with the status reason phrase as title.
  • Bean validation failures are reported as constraint-violation with a violations[] extension member.
  • When tracing is enabled (OTEL_TRACES_EXPORTER != none), every problem carries a traceId member to look the request up in the tracing backend.
  • Unhandled exceptions become a 500 problem without internals and are logged once at ERROR.
  • The OpenAPI spec documents ProblemDetail responses for every operation. The client is generated from the new java-client/specs/otis-api-1.1.0.yml (1.0.1 stays in place) and gains ProblemDetails.from(ApiException).
  • CLAUDE.md now states that the client uses Jackson and describes the problem details.
  • OpenSpec change add-problem-details (proposal, spec, design, tasks) and the OpenSpec scaffolding are included.

Compatibility (old plugins)

  • Paths, methods, success status codes, success bodies and error status codes of /otis/** and /search/** do not change. Only the error body and its Content-Type change. Released velocity-plugin builds only evaluate status codes (404/500).
  • ExistingEndpointsCompatibilityTest was written first and verified against unchanged main. It still passes after the switch.
  • javap -public of the generated client before and after: additions only (ProblemDetail, ProblemViolation and their builders, ProblemDetails).
  • velocity-plugin compiles and shadowJar builds without source changes.

Deviations / notes

  • micronaut-problem-json 3.9.0 is based on org.zalando:problem. Its error processor is deprecated, so the body provider is replaced, and extension members are flattened to the top level as RFC 9457 requires.
  • micronaut-tracing-opentelemetry-http marks every server span with status >= 400 as ERROR. That differs from the OTel semantic conventions, and there is no switch for it. The spec was narrowed to "problem rendering does not touch the span" instead of replacing the built-in tracing filter.
  • Integration tests run on in-memory H2 (application-test.yml, CI has no Docker) with transactional = false, because two transaction managers make micronaut-test's transaction listener ambiguous.

Test plan

  • ./gradlew clean build: 50 tests, 0 failures, 1 skipped (pre-existing disabled OtisTest)
  • Characterization tests green on main and on this branch
  • Client javap diff contains additions only; velocity-plugin shadowJar builds unchanged

https://claude.ai/code/session_012BmpdMdQ5wwagagQvfcq8S

Extension members are written as top-level members of the problem.

Claude-Session: https://claude.ai/code/session_012BmpdMdQ5wwagagQvfcq8S
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Test results

 33 files   33 suites   38s ⏱️
 50 tests  49 ✅ 1 💤 0 ❌
150 runs  147 ✅ 3 💤 0 ❌

Results for commit bf6086d.

♻️ This comment has been updated with latest results.

@TheMeinerLP
TheMeinerLP merged commit 2959ad6 into main Oct 7, 2026
12 of 13 checks passed
@TheMeinerLP
TheMeinerLP deleted the feat/problem-details branch October 7, 2026 10:55
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