Skip to content

WI-003: #18 ProblemDetails has custom MarshalJSON but no UnmarshalJSON — problem responses can't round-trip - #21

Draft
rluders wants to merge 1 commit into
mainfrom
weave/wi-003-18-problemdetails-has-custom-marshaljson
Draft

rluders wants to merge 1 commit into
mainfrom
weave/wi-003-18-problemdetails-has-custom-marshaljson

Conversation

@rluders

@rluders rluders commented Oct 12, 2026

Copy link
Copy Markdown
Owner

Work item WI-003 of work package WP-001 (GitHub issues).

`ProblemDetails.MarshalJSON` flattens `Extensions` to the top level per RFC 9457 (`type`/`title`/`status`/`detail`/`instance` plus arbitrary extension keys, all siblings). There's no corresponding `UnmarshalJSON`, so decoding a problem response back into a `ProblemDetails` loses every extension member — `json.Unmarshal` only populates the struct's declared fields and silently drops the rest, since `Extensions` isn't itself a tagged field that captures leftover keys.

This bites API clients and tests that need to decode a problem response and inspect an extension (e.g. a `messageKey` i18n hint, or a `correlationId`) — there's no way to get it back out via the type this library provides.

Requested: a matching `UnmarshalJSON` that reads the known fields and stuffs everything else into `Extensions`, so `ProblemDetails` round-trips through JSON.

Implemented by the Weave Autoloop, attempt 1, execution exe_4feb2775d52c.

Changed files:

  • problem_details.go
  • problem_details_test.go

…N — problem responses can't round-trip

Implemented by the Weave Autoloop, attempt 1 (execution exe_4feb2775d52c).
@coderabbitai

coderabbitai Bot commented Oct 12, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 91.66667% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.35%. Comparing base (9b55b5e) to head (57a0e40).

Files with missing lines Patch % Lines
problem_details.go 91.66% 1 Missing and 1 partial ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #21      +/-   ##
==========================================
+ Coverage   83.60%   84.35%   +0.75%     
==========================================
  Files          14       14              
  Lines         500      524      +24     
==========================================
+ Hits          418      442      +24     
  Misses         63       63              
  Partials       19       19              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rluders

rluders commented Oct 12, 2026

Copy link
Copy Markdown
Owner Author

Weave review: approved (execution exe_ab89e8a56b69)

  • Reviewer by agent go-reviewer: approved — The change meets the work item. I read the code and tests and checked the step report. I did not re-run the tests myself.

Acceptance criteria

  1. A matching UnmarshalJSON reads the known fields.

    • Implemented at problem_details.go:52-84.
    • The known fields (type, title, status, detail, instance) are decoded at problem_details.go:53-62.
    • It uses a pointer receiver, and it assigns *p only after both decodes succeed (problem_details.go:72-82), so a failed decode leaves the target unchanged.
    • Tests: TestProblemDetailsJSONRoundTrip (problem_details_test.go:24) checks the known fields. TestProblemDetailsUnmarshalJSONInvalid (problem_details_test.go:69) checks that a bad status type returns an error.
  2. Every other top-level member goes into Extensions.

    • Implemented at problem_details.go:64-81. The known keys are deleted from the member map (problem_details.go:68-70), and the rest become Extensions.
    • Test: TestProblemDetailsJSONRoundTrip (problem_details_test.go:33-36) uses messageKey and correlationId, the two examples from the work item.
  3. ProblemDetails round-trips through JSON.

    • The round-trip test compares the original and decoded values with reflect.DeepEqual (problem_details_test.go:49).
    • TestProblemDetailsUnmarshalJSONNoExtensions (problem_details_test.go:54) shows that a payload with no extensions leaves Extensions nil, even if the target had stale extensions before.
  4. Public API is documented, and the change is minimal.

    • UnmarshalJSON has a doc comment (problem_details.go:50-51).
    • Only problem_details.go and its test file changed.
  5. go vet ./... and go test -count=1 ./... both exit 0, according to report.json.

Minor notes (not blocking)

  • MarshalJSON skips an extension keyed "extensions" (problem_details.go:41), but UnmarshalJSON would keep a wire member with that name. That only affects unusual payloads and doe…
  • Person: approved — Operator review (Orkestra dogfood operator; this is NOT a GitHub review): diff read. UnmarshalJSON mirrors MarshalJSON: known RFC 9457 members typed, every other top-level member into Extensions, nil Extensions when none, wrong types rejected. Tests cover round trip, no extensions, invalid input. CI 8/8 green. Note for the maintainer: numeric extension values decode as float64 (encoding/json default). Ready for a human merge decision on GitHub; Orkestra will not merge.

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.

2 participants