mirror of https://github.com/celery/kombu.git
Fixes for #290
This commit is contained in:
parent
48853b14bb
commit
620e2b62f5
|
@ -8,9 +8,15 @@
|
|||
|
||||
3.0.8
|
||||
=====
|
||||
:release-date: 2013-12-16 16:00 P.M UTC
|
||||
:release-date: 2013-12-16 17:00 P.M UTC
|
||||
:release-by: Ask Solem
|
||||
|
||||
- Serializer: loads and dumps now wraps exceptions raised into
|
||||
:exc:`~kombu.exceptions.DecodeError` and
|
||||
:exc:`kombu.exceptions.EncodeError` respectively.
|
||||
|
||||
Contributed by Ionel Cristian Maries
|
||||
|
||||
- Redis: Would attempt to read from the wrong connection if a select/epoll/kqueue
|
||||
exception event happened.
|
||||
|
||||
|
|
|
@ -24,13 +24,19 @@ class KombuError(Exception):
|
|||
"""Common subclass for all Kombu exceptions."""
|
||||
pass
|
||||
|
||||
|
||||
class SerializationError(KombuError):
|
||||
"""Failed to encode a message."""
|
||||
"""Failed to serialize/deserialize content."""
|
||||
|
||||
|
||||
class EncodeError(SerializationError):
|
||||
"""Cannot encode object."""
|
||||
pass
|
||||
|
||||
class DeserializationError(KombuError):
|
||||
"""Failed to decode a message."""
|
||||
pass
|
||||
|
||||
class DecodeError(SerializationError):
|
||||
"""Cannot decode object."""
|
||||
|
||||
|
||||
class NotBoundError(KombuError):
|
||||
"""Trying to call channel dependent method on unbound entity."""
|
||||
|
|
|
@ -18,10 +18,13 @@ except ImportError: # pragma: no cover
|
|||
cpickle = None # noqa
|
||||
|
||||
from collections import namedtuple
|
||||
from contextlib import contextmanager
|
||||
|
||||
from .exceptions import SerializerNotInstalled, ContentDisallowed, SerializationError, DeserializationError
|
||||
from .five import BytesIO, text_t
|
||||
from .utils import entrypoints, wrap_exceptions
|
||||
from .exceptions import (
|
||||
ContentDisallowed, DecodeError, EncodeError, SerializerNotInstalled
|
||||
)
|
||||
from .five import BytesIO, reraise, text_t
|
||||
from .utils import entrypoints
|
||||
from .utils.encoding import str_to_bytes, bytes_t
|
||||
|
||||
__all__ = ['pickle', 'loads', 'dumps', 'register', 'unregister']
|
||||
|
@ -44,6 +47,17 @@ pickle_protocol = int(os.environ.get('PICKLE_PROTOCOL', 2))
|
|||
codec = namedtuple('codec', ('content_type', 'content_encoding', 'encoder'))
|
||||
|
||||
|
||||
@contextmanager
|
||||
def _reraise_errors(wrapper,
|
||||
include=(Exception, ), exclude=(SerializerNotInstalled, )):
|
||||
try:
|
||||
yield
|
||||
except exclude:
|
||||
raise
|
||||
except include as exc:
|
||||
reraise(wrapper, wrapper(exc), sys.exc_info()[2])
|
||||
|
||||
|
||||
def pickle_loads(s, load=pickle_load):
|
||||
# used to support buffer objects
|
||||
return load(BytesIO(s))
|
||||
|
@ -116,7 +130,6 @@ class SerializerRegistry(object):
|
|||
raise SerializerNotInstalled(
|
||||
'No encoder installed for {0}'.format(name))
|
||||
|
||||
@wrap_exceptions(SerializationError)
|
||||
def dumps(self, data, serializer=None):
|
||||
if serializer == 'raw':
|
||||
return raw_encode(data)
|
||||
|
@ -134,6 +147,7 @@ class SerializerRegistry(object):
|
|||
|
||||
# For Unicode objects, force it into a string
|
||||
if not serializer and isinstance(data, text_t):
|
||||
with _reraise_errors(EncodeError, exclude=()):
|
||||
payload = data.encode('utf-8')
|
||||
return 'text/plain', 'utf-8', payload
|
||||
|
||||
|
@ -145,11 +159,11 @@ class SerializerRegistry(object):
|
|||
content_type = self._default_content_type
|
||||
content_encoding = self._default_content_encoding
|
||||
|
||||
with _reraise_errors(EncodeError):
|
||||
payload = encoder(data)
|
||||
return content_type, content_encoding, payload
|
||||
encode = dumps # XXX compat
|
||||
|
||||
@wrap_exceptions(DeserializationError)
|
||||
def loads(self, data, content_type, content_encoding,
|
||||
accept=None, force=False):
|
||||
if accept is not None:
|
||||
|
@ -164,9 +178,11 @@ class SerializerRegistry(object):
|
|||
if data:
|
||||
decode = self._decoders.get(content_type)
|
||||
if decode:
|
||||
with _reraise_errors(DecodeError):
|
||||
return decode(data)
|
||||
if content_encoding not in SKIP_DECODE and \
|
||||
not isinstance(data, text_t):
|
||||
with _reraise_errors(DecodeError):
|
||||
return _decode(data, content_encoding)
|
||||
return data
|
||||
decode = loads # XXX compat
|
||||
|
@ -280,6 +296,7 @@ def raw_encode(data):
|
|||
payload = data
|
||||
if isinstance(payload, text_t):
|
||||
content_encoding = 'utf-8'
|
||||
with _reraise_errors(EncodeError, exclude=()):
|
||||
payload = payload.encode(content_encoding)
|
||||
else:
|
||||
content_encoding = 'binary'
|
||||
|
|
|
@ -7,7 +7,7 @@ import sys
|
|||
|
||||
from base64 import b64decode
|
||||
|
||||
from kombu.exceptions import ContentDisallowed
|
||||
from kombu.exceptions import ContentDisallowed, EncodeError, DecodeError
|
||||
from kombu.five import text_t, bytes_t
|
||||
from kombu.serialization import (
|
||||
registry, register, SerializerNotInstalled,
|
||||
|
@ -186,6 +186,15 @@ class test_Serialization(Case):
|
|||
call('pickle'), call('yaml'), call('doomsday')
|
||||
])
|
||||
|
||||
def test_reraises_EncodeError(self):
|
||||
with self.assertRaises(EncodeError):
|
||||
dumps([object()], serializer='json')
|
||||
|
||||
def test_reraises_DecodeError(self):
|
||||
with self.assertRaises(DecodeError):
|
||||
loads(object(), content_type='application/json',
|
||||
content_encoding='utf-8')
|
||||
|
||||
def test_json_loads(self):
|
||||
self.assertEqual(
|
||||
py_data,
|
||||
|
|
|
@ -429,20 +429,3 @@ def maybe_fileno(f):
|
|||
return fileno(f)
|
||||
except FILENO_ERRORS:
|
||||
pass
|
||||
|
||||
def wrap_exceptions(exception, catch=Exception):
|
||||
"""
|
||||
Catch the exception specified by ``catch`` and raise ``exception`` instead with
|
||||
the old exception as the value.
|
||||
"""
|
||||
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
def wrap_exceptions_wrapper(*args, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except catch as exc:
|
||||
raise exception(exc)
|
||||
return wrap_exceptions_wrapper
|
||||
|
||||
return decorator
|
||||
|
|
Loading…
Reference in New Issue