Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Changelog
applied. Uninstalling from the same panel removes the PAS plugin
and the per-user JWT signing secrets.

- #117 Answer a refused field value with 400, not 500
- #109 Add a partition operation endpoint
- #106 Fix single-valued UID reference fields not settable through the JSON API
- #112 Allow updating the Laboratory through the API
Expand Down
22 changes: 15 additions & 7 deletions src/senaite/jsonapi/fieldmanagers.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from senaite.jsonapi import api
from senaite.jsonapi import logger
from senaite.jsonapi import underscore as u
from senaite.jsonapi.exceptions import BadRequestError
from senaite.jsonapi.interfaces import IFieldManager
from zope import interface
from zope.interface import implementer
Expand Down Expand Up @@ -86,7 +87,12 @@ def _set(self, instance, value, **kw):
# TODO: Check security on the field level
return self.field.set(instance, value)
except (WrongType, WrongContainedType):
raise TypeError("WrongType: Field={} Value={}".format(
# A value the schema refuses came from the request, so this
# is a bad request and not a server fault. Raised as a
# TypeError it answered 500, and a caller composing many
# objects could not tell which payload was at fault,
# because the type carried no more than the message.
raise BadRequestError("WrongType: Field={} Value={}".format(
self.field, value))

def _get(self, instance, **kw):
Expand Down Expand Up @@ -369,8 +375,8 @@ def _set(self, instance, value, **kw):
# validate the value
error = self.field.validate(value, instance)
if error:
raise ValueError("Invalid value for field {}: {}"
.format(self.name, error))
raise BadRequestError("Invalid value for field {}: {}"
.format(self.name, error))

# id fields take only strings
if self.name == "id":
Expand Down Expand Up @@ -598,8 +604,9 @@ def set(self, instance, value, **kw): # noqa
# Handle non multi valued fields
if not self.multi_valued:
if len(ref) > 1:
raise ValueError("Multiple values given for single valued "
"field {}".format(repr(self.field)))
raise BadRequestError(
"Multiple values given for single valued "
"field {}".format(repr(self.field)))
else:
ref = ref[0]
return self._set(instance, ref, **kw)
Expand Down Expand Up @@ -735,8 +742,9 @@ def set(self, instance, value, **kw): # noqa
# (None clears the reference). Multi valued fields keep the list.
if not self.multi_valued:
if len(refs) > 1:
raise ValueError("Multiple values given for single valued "
"field {}".format(repr(self.field)))
raise BadRequestError(
"Multiple values given for single valued "
"field {}".format(repr(self.field)))
refs = refs[0] if refs else None

return self._set(instance, refs, **kw)
Expand Down
Loading