fix(api): handle non-object payloads in edge identity update-traits#7952
fix(api): handle non-object payloads in edge identity update-traits#7952zain-asif-dev wants to merge 1 commit into
Conversation
TraitModel(**request.data) raised an uncaught TypeError when request.data was a list instead of a dict, resulting in an unhandled 500 response. Switching to TraitModel.model_validate() surfaces a ValidationError instead, but pyngo.drf_error_details() then crashes with an IndexError because the top-level model_type error it produces has an empty loc tuple. Reject non-mapping payloads explicitly before validation so callers get a proper 400 response. Signed-off-by: Zain Asif <zainasif.jutt1@gmail.com>
|
@zain-asif-dev is attempting to deploy a commit to the Flagsmith Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe Estimated code review effort: 2 (Simple) | ~10 minutes Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant UpdateTraitsView
participant TraitModel
Client->>UpdateTraitsView: request.data
UpdateTraitsView->>UpdateTraitsView: check request.data is mapping
alt not a mapping
UpdateTraitsView-->>Client: 400 ValidationError (non_field_errors)
else is a mapping
UpdateTraitsView->>TraitModel: model_validate(request.data)
alt pydantic ValidationError
TraitModel-->>UpdateTraitsView: ValidationError
UpdateTraitsView-->>Client: 400 drf_error_details
else valid
TraitModel-->>UpdateTraitsView: trait instance
UpdateTraitsView-->>Client: success response
end
end
Related issues: Not specified in the provided context. Related PRs: Not specified in the provided context. Suggested labels: bug, api Suggested reviewers: Not specified in the provided context. PoemA rabbit checked the data shape, Comment |
docs/if required so people know about the feature.Changes
Closes #7951
The edge identity
update-traitsendpoint raised an unhandled 500 error when the request body was a JSON array instead of an object, becauseTraitModel(**request.data)raises a bareTypeErrorfor non-mapping input, which was not caught by the existingpydantic.ValidationErrorhandler.Switching to
TraitModel.model_validate(request.data)correctly turns that into apydantic.ValidationError, but doing so uncovers a second issue:pyngo.drf_error_details()assumes every error inValidationError.errors()has a non-emptyloc, which isn't true for a top-levelmodel_typeerror (thelocis()when the payload itself isn't an object). That call then raises anIndexError, so the 500 doesn't go away, it just changes shape.This PR rejects non-mapping payloads up front with a normal DRF
ValidationError(400), before either of those code paths is reached, and switches the remaining case over tomodel_validatefor more consistent validation behavior.How did you test this code?
Added a regression test (
test_edge_identities_update_trait__malformed_traits_payload__returns_400) that PUTs a JSON array to theupdate-traitsendpoint and asserts a 400 response, with no DynamoDB write attempted. Verified it fails against the old code (500) and passes with the fix. Also ran the fulltests/integration/edge_api/identities/test_edge_identity_viewset.pysuite (22 passed),ruff check/ruff format --check, andmypyon the changed file.