Return 400 on a malformed request envelope instead of 500 (#19)#21
Return 400 on a malformed request envelope instead of 500 (#19)#21phillipclapham wants to merge 1 commit into
Conversation
Wrap envelope parsing in the /ldp/messages route so bad JSON or a body that fails envelope validation returns a structured LDP error at 400 rather than leaking as an unhandled 500. Extract the Starlette app into _build_app() so the route is testable with a client without binding a socket; run() is unchanged behaviourally.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe Envelope Parsing Hardening
Sequence Diagram(s)sequenceDiagram
participant Client
participant _build_app as POST /ldp/messages
participant _bad_request
participant handle_message
Client->>"POST /ldp/messages": request with body
alt malformed JSON / Unicode error
"POST /ldp/messages"->>_bad_request: JSONDecodeError or UnicodeDecodeError
_bad_request-->>Client: 400 · LdpError MALFORMED_ENVELOPE
else envelope schema invalid
"POST /ldp/messages"->>_bad_request: ValidationError
_bad_request-->>Client: 400 · LdpError MALFORMED_ENVELOPE
else valid LdpEnvelope
"POST /ldp/messages"->>handle_message: LdpEnvelope
handle_message-->>"POST /ldp/messages": LdpEnvelope response
"POST /ldp/messages"-->>Client: 200 · model_dump(by_alias=True)
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Closes #19.
The
/ldp/messagesroute didn't wraprequest.json()/model_validate, so a malformed request envelope — bad JSON, or a body that fails envelope validation — surfaced as a 500 rather than a 400.This parses the envelope defensively:
JSONDecodeError) or a bad encoding (UnicodeDecodeError) → 400ValidationError) → 400handle_message) still propagates as 500 — it's ours, not the peer's, and stays observableThe 400 body is a structured
LdpError(transport/MALFORMED_ENVELOPE). The bundled client callsraise_for_status()before parsing, so the non-envelope error shape doesn't affect it. (Happy to switch to a non-retryable category if you'd prefer for client errors.)To make the route testable without binding a socket, the Starlette app moves into a
_build_app()helper;run()is otherwise unchanged.Tests cover: malformed JSON → 400, invalid envelope → 400, valid envelope still dispatches, a SESSION_PROPOSE→SESSION_ACCEPT round-trip confirming
PayloadModeserializes over the wire, identity route unaffected. Starlette is in the[server]extra (not[dev]), so the route testspytest.importorskipit — they skip rather than fail collection in a dev-only env. (Minor:TestClientemits aStarletteDeprecationWarningabout httpx2 on starlette 1.2.1 — left your deps untouched, flagging in case you'd rather pin httpx2.)Summary by CodeRabbit
Bug Fixes
Tests