Skip to content

Commit 7df6bc5

Browse files
committed
Fix silent serialization failure when publishing non-JSON-serializable objects
1 parent 07ddfab commit 7df6bc5

3 files changed

Lines changed: 44 additions & 2 deletions

File tree

pubnub/enums.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class PNStatusCategory(Enum):
3939
PNInternalExceptionCategory = 17
4040
PNSubscriptionChangedCategory = 18
4141
PNConnectionErrorCategory = 19
42+
PNSerializationErrorCategory = 20
4243

4344

4445
class PNOperationType(object):

pubnub/utils.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from pubnub.models.consumer.common import PNStatus
1515
from pubnub.errors import PNERR_JSON_NOT_SERIALIZABLE
1616
from pubnub.exceptions import PubNubException
17+
from pubnub.models.consumer.pn_error_data import PNErrorData
1718

1819

1920
def get_data_for_user(data):
@@ -29,10 +30,17 @@ def get_data_for_user(data):
2930
def write_value_as_string(data):
3031
try:
3132
return json.dumps(data)
32-
except TypeError:
33-
raise PubNubException(
33+
except TypeError as e:
34+
exc = PubNubException(
35+
errormsg=str(e),
3436
pn_error=PNERR_JSON_NOT_SERIALIZABLE
3537
)
38+
status = PNStatus()
39+
status.category = PNStatusCategory.PNSerializationErrorCategory
40+
status.error = True
41+
status.error_data = PNErrorData(str(exc), exc)
42+
exc.status = status
43+
raise exc
3644

3745

3846
def url_encode(data):
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from datetime import datetime
2+
3+
import pytest
4+
5+
from pubnub.enums import PNStatusCategory
6+
from pubnub.exceptions import PubNubAsyncioException
7+
from pubnub.models.consumer.common import PNStatus
8+
from pubnub.models.consumer.pn_error_data import PNErrorData
9+
from pubnub.pubnub_asyncio import PubNubAsyncio
10+
from tests.helper import pnconf_copy
11+
12+
13+
@pytest.mark.asyncio
14+
async def test_publish_non_serializable_returns_usable_error():
15+
pubnub = PubNubAsyncio(pnconf_copy())
16+
17+
result = await pubnub.publish().channel("ch1").message({
18+
"text": "Hello",
19+
"timestamp": datetime.now(),
20+
}).future()
21+
22+
assert isinstance(result, PubNubAsyncioException)
23+
assert result.is_error() is True
24+
assert isinstance(result.status, PNStatus)
25+
assert result.status.error is True
26+
assert result.status.category == PNStatusCategory.PNSerializationErrorCategory
27+
assert isinstance(result.status.error_data, PNErrorData)
28+
assert str(result) == (
29+
"Trying to publish not JSON serializable object: "
30+
"Object of type datetime is not JSON serializable"
31+
)
32+
33+
await pubnub.stop()

0 commit comments

Comments
 (0)