django / channels

Developer-friendly asynchrony for Django
https://channels.readthedocs.io
BSD 3-Clause "New" or "Revised" License
6.11k stars 800 forks source link

Djangos get_response method seems to return a None and channels crashes because of it #1952

Closed Kaju-Bubanja closed 11 months ago

Kaju-Bubanja commented 2 years ago
- Channels http.py handle method errors with following stacktrace

2022-11-09 16:38:14.502 ERROR daphne.server:server.py:293 Exception inside application: 'NoneType' object has no attribute 'items' Traceback (most recent call last): File "/home/username/app/lib/python3.6/site-packages/channels/staticfiles.py", line 41, in call dict(scope, static_base_url=self.base_url), receive, send File "/home/username/app/lib/python3.6/site-packages/channels/staticfiles.py", line 56, in call return await super().call(scope, receive, send) File "/home/username/app/lib/python3.6/site-packages/channels/http.py", line 198, in call await self.handle(scope, async_to_sync(send), body_stream) File "/home/username/app/lib/python3.6/site-packages/asgiref/sync.py", line 444, in call ret = await asyncio.wait_for(future, timeout=None) File "/usr/lib/python3.6/asyncio/tasks.py", line 339, in wait_for return (yield from fut) File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run result = self.fn(*self.args, *self.kwargs) File "/home/username/app/lib/python3.6/site-packages/asgiref/sync.py", line 486, in thread_handler return func(args, **kwargs) File "/home/username/app/lib/python3.6/site-packages/channels/http.py", line 255, in handle for response_message in self.encode_response(response): File "/home/username/app/lib/python3.6/site-packages/channels/http.py", line 311, in encode_response for header, value in response.items(): AttributeError: 'NoneType' object has no attribute 'items'

Djangos get_response method seems to return a None. Not sure if this is a channels bug and it should be able to handle None as a response or this is a Django bug and `self.get_response(request)` should never return None
- How you're running Channels (runserver? daphne/runworker? Nginx/Apache in front?)
`sudo /home/username/app/bin/python manage.py runserver 0.0.0.0:80 --insecure` no nginx or apache

The application definition is:

from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack from channels.security.websocket import AllowedHostsOriginValidator from django.urls import re_path

application = ProtocolTypeRouter({

(http->django views is added by default)

'websocket': AllowedHostsOriginValidator(
    AuthMiddlewareStack(
        URLRouter([
            re_path(r"^app_name/ws", AppConsumer.as_asgi()),
        ])
    )
)

})


and the consumer is defined as:

from django.db import close_old_connections from channels.generic.websocket import AsyncJsonWebsocketConsumer

class AppConsumer(AsyncJsonWebsocketConsumer): async def connect(self): await self.accept() await self.channel_layer.group_add("app_ws", self.channel_name)

async def disconnect(self, close_code):
    await self.channel_layer.group_discard("app_ws", self.channel_name)

async def app_message(self, event):
    await self.send_json(event)

async def receive_json(self, content, **kwargs):
    if 'request' in content:
        close_old_connections()
        await self.send_json({"text": get_text(), "channel": content['request']})
carltongibson commented 11 months ago

Sorry, there's not enough to say anything here. A minimal reproduce would be helpful.