Skip to content

Commit

Permalink
adding a Python3 fix to JsonRPC serializer
Browse files Browse the repository at this point in the history
  • Loading branch information
cloud-rocket committed Nov 23, 2021
1 parent 75e51e8 commit 5a205e3
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 3 deletions.
22 changes: 20 additions & 2 deletions aio_pika/patterns/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,18 +399,36 @@ async def unregister(self, func):
self.routes.pop(queue.name)


class JsonRPCError(Exception):
def __init__(self, orig_exp_type, message=None, *args):
super(JsonRPCError, self).__init__(message, args)
self.orig_exp_type = orig_exp_type


class JsonRPC(RPC):
SERIALIZER = json
CONTENT_TYPE = "application/json"

def serialize(self, data: Any) -> bytes:
return self.SERIALIZER.dumps(data, ensure_ascii=False, default=repr)
return self.SERIALIZER.dumps(
data, ensure_ascii=False, default=repr).encode('ascii')

def deserialize(self, data: Any) -> bytes:
res = super().deserialize(data)
if isinstance(res, dict) and "error" in res:
res = JsonRPCError(res['error']['type'],
res['error']['message'],
res['error']['args'])
return res

def serialize_exception(self, exception: Exception) -> bytes:
return self.serialize(
{
"error": {
"type": exception.__class__.__name__,
"type": f'{exception.__module__}.'
f'{exception.__class__.__name__}'
if hasattr(exception, '__module__')
else exception.__class__.__name__,
"message": repr(exception),
"args": exception.args,
},
Expand Down
52 changes: 51 additions & 1 deletion tests/test_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from aio_pika import Message
from aio_pika.exceptions import DeliveryError
from aio_pika.message import IncomingMessage
from aio_pika.patterns.rpc import RPC
from aio_pika.patterns.rpc import RPC, JsonRPC, JsonRPCError
from aio_pika.patterns.rpc import log as rpc_logger
from tests import get_random_name

Expand All @@ -19,6 +19,14 @@ def rpc_func(*, foo, bar):
return {"foo": "bar"}


class CustomException(Exception):
pass


def rpc_raise_exception(*, foo, bar):
raise CustomException('foo bar')


class TestCase:
async def test_simple(self, channel: aio_pika.Channel):
rpc = await RPC.create(channel, auto_delete=True)
Expand Down Expand Up @@ -172,3 +180,45 @@ async def test_register_twice(self, channel: aio_pika.Channel):
await rpc.unregister(rpc_func)

await rpc.close()

async def test_jsonrpc_simple(self, channel: aio_pika.Channel):
rpc = await JsonRPC.create(channel, auto_delete=True)

await rpc.register("test.rpc", rpc_func, auto_delete=True)

result = await rpc.proxy.test.rpc(foo=None, bar=None)
assert result == {"foo": "bar"}

await rpc.unregister(rpc_func)
await rpc.close()

# Close already closed
await rpc.close()

async def test_jsonrpc_assert(self, channel: aio_pika.Channel):
rpc = await JsonRPC.create(channel, auto_delete=True)

await rpc.register("test.rpc", rpc_func, auto_delete=True)

with pytest.raises(JsonRPCError) as excinfo:
await rpc.proxy.test.rpc(foo=True, bar=None)
assert excinfo.value.orig_exp_type == 'AssertionError'

await rpc.unregister(rpc_func)
await rpc.close()

async def test_jsonrpc_error(self, channel: aio_pika.Channel):
rpc = await JsonRPC.create(channel, auto_delete=True)

await rpc.register("test.rpc_error", rpc_raise_exception,
auto_delete=True)

with pytest.raises(Exception) as excinfo:
await rpc.proxy.test.rpc_error(foo=True, bar=None)
assert excinfo.value.orig_exp_type == 'tests.test_rpc.CustomException'

with pytest.raises(JsonRPCError):
await rpc.proxy.test.rpc_error(foo=True, bar=None)

await rpc.unregister(rpc_raise_exception)
await rpc.close()

0 comments on commit 5a205e3

Please sign in to comment.