Skip to content

Answer a refused field value with 400, not 500 - #117

Open
ramonski wants to merge 2 commits into
2.xfrom
fix/refused-value-answers-400
Open

ramonski wants to merge 2 commits into
2.xfrom
fix/refused-value-answers-400

Conversation

@ramonski

Copy link
Copy Markdown
Contributor

Description of the issue/feature this PR addresses

A value the schema will not take comes from the request, so it is a bad request. The field managers raise a bare TypeError or ValueError for these, which plone.jsonapi.core renders as a 500: the caller is told the server broke when in fact the payload did.

It also costs the error its identity. A caller writing many objects in one run can catch an APIError and carry on, naming the object that failed, but a TypeError carries nothing to distinguish a refused value from a genuine fault inside the server, so it has to be let through and ends the whole run with the field name and nothing else.

Current behavior before PR

POST /senaite/@@API/senaite/v1/update/<uid>
{"sort_key": 1}

HTTP/1.1 500 Internal Server Error
{"message": "sort_key: wrong type", ...}

Desired behavior after PR is merged

HTTP/1.1 400 Bad Request
{"message": "sort_key: wrong type", ...}

Four raise sites, all of them reporting a value that arrived in the payload: a wrong type, a field that failed its own validator, and two copies of "multiple values for a single valued field". The messages are unchanged, only the exception type is, from TypeError/ValueError to BadRequestError.

Verification

  • POST a wrong-typed value (an int into a schema.Float) and a value that fails a field validator; both answer 400 with the same message as before.
  • A value the schema accepts is unaffected.

A value the schema will not take comes from the request, so it is a bad
request. The field managers raised a bare TypeError or ValueError for
these, which plone.jsonapi.core renders as a 500: the caller is told
the server broke when in fact the payload did.

It also cost the error its identity. A caller writing many objects in
one run could catch an APIError and carry on, naming the object that
failed, but a TypeError carried nothing to distinguish a refused value
from a genuine fault inside the server, so it had to be let through and
ended the whole run with the field name and nothing else.

Four raise sites, all of them reporting a value that arrived in the
payload: a wrong type, a field that failed its own validator, and two
copies of "multiple values for a single valued field". The messages are
unchanged.
@ramonski
ramonski requested a review from xispa October 10, 2026 08:24
@ramonski ramonski added Bug 🐞 Something is broken Enhancement ✨ Improvement to existing functionality labels Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug 🐞 Something is broken Enhancement ✨ Improvement to existing functionality

Development

Successfully merging this pull request may close these issues.

1 participant