Skip to content

Commit

Permalink
Uses instance attrs for deserialization exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
jfinkels committed Apr 27, 2016
1 parent 4a1b818 commit 91da84b
Showing 1 changed file with 40 additions and 66 deletions.
106 changes: 40 additions & 66 deletions flask_restless/serialization/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# information, see LICENSE.AGPL and LICENSE.BSD.
"""Exceptions that arise from serialization or deserialization."""


class SerializationException(Exception):
"""Raised when there is a problem serializing an instance of a
SQLAlchemy model to a dictionary representation.
Expand Down Expand Up @@ -60,31 +61,28 @@ class DeserializationException(Exception):
"""Raised when there is a problem deserializing a Python dictionary to an
instance of a SQLAlchemy model.
Subclasses that wish to provide more detailed about the problem
should set the :attr:`detail` attribute to be a string, either as a
class-level attribute or as an instance attribute, and the
:attr:`status` attribute to be an integer representing an HTTP
status code.
`status` is an integer representing the HTTP status code that
corresponds to this error. If not specified, it is set to 400,
representing :http:status:`400`.
"""
`detail` is a string describing the problem in more detail. If
provided, this will be incorporated in the return value of
:meth:`.message`.
status = 400
Each of the keyword arguments `status` and `detail` are assigned
directly to instance-level attributes :attr:`status` and
:attr:`detail`.
def __init__(self, *args, **kw):
"""

def __init__(self, status=400, detail=None, *args, **kw):
super(DeserializationException, self).__init__(*args, **kw)

#: A string describing the problem in more detail.
#:
#: Subclasses must set this attribute to be a string describing
#: the problem that cause this exception.
self.detail = None
self.detail = detail

#: The HTTP status code corresponding to this error.
#:
#: By default, this is :http:status:`400`, but subclasses should
#: set this to be an integer representing an HTTP status code
#: appropriate for the particular error.
self.status = self.status
self.status = status

def message(self):
"""Returns a more detailed description of the problem as a
Expand All @@ -104,20 +102,17 @@ class NotAList(DeserializationException):
"""

def __init__(self, relation_name=None, *args, **kw):
super(NotAList, self).__init__(*args, **kw)

#: The relationship in which a linkage object is missing information.
self.relation_name = relation_name

if self.relation_name is not None:
if relation_name is not None:
inner = ('in linkage for relationship'
' "{0}"').format(self.relation_name)
' "{0}"').format(relation_name)
else:
inner = ''

self.detail = ('data element {0}must be a list when'
' calling deserialize_many(); maybe you meant to call'
' deserialize()?').format(inner)
detail = ('"data" element {0}must be a list when calling'
' deserialize_many(); maybe you meant to call'
' deserialize()?').format(inner)

super(NotAList, self).__init__(detail=detail, *args, **kw)


class ClientGeneratedIDNotAllowed(DeserializationException):
Expand All @@ -126,12 +121,10 @@ class ClientGeneratedIDNotAllowed(DeserializationException):
"""

status = 403

def __init__(self, *args, **kw):
super(ClientGeneratedIDNotAllowed, self).__init__(*args, **kw)

self.detail = 'Server does not allow client-generated IDS'
detail = 'Server does not allow client-generated IDS'
sup = super(ClientGeneratedIDNotAllowed, self)
sup.__init__(status=403, detail=detail, *args, **kw)


class ConflictingType(DeserializationException):
Expand All @@ -149,29 +142,17 @@ class ConflictingType(DeserializationException):
"""

status = 409

def __init__(self, expected_type, given_type, relation_name=None, *args,
**kw):
super(ConflictingType, self).__init__(*args, **kw)

#: The name of the relationship with a conflicting type.
self.relation_name = relation_name

#: The expected type name for the related model.
self.expected_type = expected_type

#: The type name given by the client for the related model.
self.given_type = given_type

if relation_name is None:
detail = 'expected type "{0}" but got type "{1}"'
detail = detail.format(expected_type, given_type)
inner = ''
else:
detail = ('expected type "{0}" but got type "{1}" in linkage'
' object for relationship "{2}"')
detail = detail.format(expected_type, given_type, relation_name)
self.detail = detail
inner = (' in linkage object for relationship'
' "{0}"').format(relation_name)
detail = 'expected type "{0}" but got type "{1}"{2}'
detail = detail.format(expected_type, given_type, inner)
sup = super(ConflictingType, self)
sup.__init__(status=409, detail=detail, *args, **kw)


class UnknownField(DeserializationException):
Expand All @@ -189,12 +170,8 @@ class UnknownField(DeserializationException):
field_type = None

def __init__(self, field, *args, **kw):
super(UnknownField, self).__init__(*args, **kw)

#: The name of the unknown field, as a string.
self.field = field

self.detail = 'model has no {0} "{1}"'.format(self.field_type, field)
detail = 'model has no {0} "{1}"'.format(self.field_type, field)
super(UnknownField, self).__init__(detail=detail, *args, **kw)


class UnknownRelationship(UnknownField):
Expand Down Expand Up @@ -228,19 +205,16 @@ class MissingInformation(DeserializationException):
element = None

def __init__(self, relation_name=None, *args, **kw):
super(MissingInformation, self).__init__(*args, **kw)

#: The relationship in which a linkage object is missing information.
self.relation_name = relation_name

if relation_name is None:
detail = 'missing "{0}" element'
detail = detail.format(self.element)
if relation_name is not None:
inner = (' in linkage object for relationship'
' "{0}"').format(relation_name)
else:
detail = ('missing "{0}" element in linkage object for'
' relationship "{1}"')
detail = detail.format(self.element, relation_name)
self.detail = detail
inner = ''
detail = 'missing "{0}" element{1}'.format(self.element, inner)
super(MissingInformation, self).__init__(detail=detail, *args, **kw)


class MissingData(MissingInformation):
Expand Down

0 comments on commit 91da84b

Please sign in to comment.