feat(apigateway): map request-contract errors to 400 instead of 500#327
Merged
Conversation
Pydantic ValidationError and malformed-JSON (json.JSONDecodeError) are client contract violations, not server faults, but they fell through the Router's generic except into a 500. Catch them explicitly and respond 400, surfacing each failure via response.set_error so the response carries the standard errors[] contract (one entry per invalid field for validation). Routed through on_error so services can still hook it. Adds mapping-router tests + mock handlers for the validation and bad-JSON paths. ApiException (418) and unhandled exceptions (500) are unchanged.
…helpers Pull the isinstance/loop/fallback out of __handle_contract_error into a pure __contract_errors builder, and share the on_error-or-log tail via a single __dispatch_error used by both error handlers. Each function is now linear.
|
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.



What
The apigateway
Routernow maps request-contract violations to 400 instead of letting them fall through to a generic 500:pydantic.ValidationError(a handler building a request model from a bad body)json.JSONDecodeError(malformed JSON body)Why
These are client errors, not server faults. Today they hit the Router's catch-all
except Exceptionand return500 internal service error, which hides the real problem from callers and looks like an outage.How
except (ValidationError, json.JSONDecodeError)branch inroute(), before the generic handler.__handle_contract_error()setscode=400and surfaces each failure viaresponse.set_error(...), so the response carries the standarderrors[]contract (one entry per invalid field for validation; a singlebodyentry for bad JSON). Routed throughon_errorso apps can still hook it.ApiException(e.g. 418) and unhandled exceptions (500) are unchanged.Tests
test_pydantic_validation_error_returns_400,test_invalid_json_body_returns_400(mapping router) + 2 mock handlers and 2 mock_request builders.