Closed gaurav-jo1 closed 6 months ago
After examining the code within the parent class (AsyncJsonWebsocketConsumer), I noticed that the encoding process for the content using json.dumps(content) was utilizing the await keyword. However, I found that removing the await and simply using json.dumps resolved the error. This adjustment allowed the "welcome message" to be sent successfully to the client side without encountering any error.
The encode_json
method is unchanged since it was introduced:
@classmethod
async def encode_json(cls, content):
return json.dumps(content)
encode_json
is defined as an async
function, but it uses json.dumps
which is a synchronous function.
Error explanation:
When we call await self.encode_json(content)
, it treats the return value of json.dumps(content)
as a coroutine, but since json.dumps
returns a string
synchronously, it raises the TypeError.
Here is the error message:
If I am misunderstanding something, please let me know.
It looks like you've overridden a method maybe and forgotten an async
.
Please post code rather than screenshots.
The async send_json method is covered by the test suite. If you could add a test demonstrating your issue, that would help to identify what you're seeing.
chats/consumers.py
class ChatConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
# Accept the connection
await self.accept()
# Send a welcome message
await self.send_json(
{
"type": "welcome_message",
"message": "Welcome to the Websocket Connection",
}
)
The error traceback is as follows:
python3.12/site-packages/channels/generic/websocket.py", line 282, in send_json
await super().send(text_data=await self.encode_json(content), close=close)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: object str can't be used in 'await' expression
The full chats/consumers.py
file can be found here: ChatConsumer file.
Here is a video demo of the error.
Compare your class:
to the base class:
By overriding this method without using the async
keyword, the await
call at the error point is receiving a string, rather than a coroutine object. You want to pass UUIDEncoder
, but you still need to declare the method async def
.
Environment Details: Operating System:
Ubuntu 24.04 LTS
Browser:Google Chrome
Django version:5.0.4
Channels version:4.1.0
pip freeze output:
asgiref==3.8.1 asyncpg==0.29.0 attrs==23.2.0 autobahn==23.6.2 Automat==22.10.0 cffi==1.16.0 channels==4.1.0 channels-redis==4.2.0 constantly==23.10.4 cryptography==42.0.5 daphne==4.1.2 Django==5.0.4 django-cors-headers==4.3.1 django-redis==5.4.0 djangorestframework==3.15.1 djangorestframework-simplejwt==5.3.1 hyperlink==21.0.0 idna==3.7 incremental==22.10.0 msgpack==1.0.8 psycopg2-binary==2.9.9 pyasn1==0.6.0 pyasn1_modules==0.4.0 pycparser==2.22 PyJWT==2.8.0 pyOpenSSL==24.1.0 python-dotenv==1.0.1 redis==5.0.3 service-identity==24.1.0 setuptools==69.5.1 six==1.16.0 sqlparse==0.5.0 Twisted==24.3.0 txaio==23.1.1 typing_extensions==4.11.0 whitenoise==6.6.0 zope.interface==6.3
Expected Behavior:
I anticipated that upon establishing a connection using AsyncJsonWebsocketConsumer, a "welcome message" would be successfully sent to the client side, similar to the behavior observed with JsonWebsocketConsumer.
Expected Behavior Code using JsonWebsocketConsumer:
Expected Response:
Actual Behavior:
I anticipated that upon establishing a connection using AsyncJsonWebsocketConsumer, a "welcome message" would be successfully sent to the client side, similar to the behavior observed with JsonWebsocketConsumer.
Actual Behavior Code:
Error Encountered: The error encountered is as follows: