Django // Daphne 500 error on all requests after version update "TypeError: object HttpResponse can't be used in 'await' expression"

Viewed 684

I have a problem where I'm getting 500 responses after updating Django from version 3.1.13 to 3.2.8.

The issue wasn't occurring on the previous version of Django, and it only occurs if both the Django Channels app and OpenCensus middleware are enabled in settings.py.

I would really appreciate if someone can help verify that my asgi.py and settings.py are configured correctly, or identify the dependency causing the issue so that I can follow through and raise a bug.

Repo that reproduces the issue

https://github.com/oscarhermoso/bug-opentelemetry-django-asgi

Daphne error as it appears in the browser

500 Internal Server Error

Exception inside application.
Daphne

ASGI entrypoint

# testproject/asgi.py

import os

from django.core.asgi import get_asgi_application

# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'testproject.settings')

from channels.auth import AuthMiddlewareStack  # noqa
from channels.routing import ProtocolTypeRouter, URLRouter  # noqa

import testproject.routing  # noqa

application = ProtocolTypeRouter({
    # Django's ASGI application to handle traditional HTTP requests
    "http": get_asgi_application(),

    # WebSocket chat handler
    "websocket": AuthMiddlewareStack(
        URLRouter(
            testproject.routing.websocket_urlpatterns
        )
    ),
})

Installed apps and middleware

# settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'channels'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'opencensus.ext.django.middleware.OpencensusMiddleware'
]

Error Dump

System check identified no issues (0 silenced).
October 09, 2021 - 10:59:03
Django version 3.2.8, using settings 'testproject.with_both'
Starting ASGI/Channels version 3.0.4 development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Internal Server Error: /
Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/vscode/.local/lib/python3.8/site-packages/django/utils/deprecation.py", line 119, in __call__
    response = self.process_response(request, response)
  File "/home/vscode/.local/lib/python3.8/site-packages/django/middleware/clickjacking.py", line 26, in process_response
    if response.get('X-Frame-Options') is not None:
AttributeError: 'coroutine' object has no attribute 'get'
Exception inside application: object HttpResponse can't be used in 'await' expression
Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.8/site-packages/channels/staticfiles.py", line 44, in __call__
    return await self.application(scope, receive, send)
  File "/home/vscode/.local/lib/python3.8/site-packages/channels/routing.py", line 71, in __call__
    return await application(scope, receive, send)
  File "/home/vscode/.local/lib/python3.8/site-packages/django/core/handlers/asgi.py", line 161, in __call__
    response = await self.get_response_async(request)
  File "/home/vscode/.local/lib/python3.8/site-packages/django/core/handlers/base.py", line 150, in get_response_async
    response = await self._middleware_chain(request)
TypeError: object HttpResponse can't be used in 'await' expression
HTTP GET / 500 [0.97, 127.0.0.1:41256]

Internal Server Error: /favicon.ico
Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/vscode/.local/lib/python3.8/site-packages/django/utils/deprecation.py", line 119, in __call__
    response = self.process_response(request, response)
  File "/home/vscode/.local/lib/python3.8/site-packages/django/middleware/clickjacking.py", line 26, in process_response
    if response.get('X-Frame-Options') is not None:
AttributeError: 'coroutine' object has no attribute 'get'
Exception inside application: object HttpResponse can't be used in 'await' expression
Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.8/site-packages/channels/staticfiles.py", line 44, in __call__
    return await self.application(scope, receive, send)
  File "/home/vscode/.local/lib/python3.8/site-packages/channels/routing.py", line 71, in __call__
    return await application(scope, receive, send)
  File "/home/vscode/.local/lib/python3.8/site-packages/django/core/handlers/asgi.py", line 161, in __call__
    response = await self.get_response_async(request)
  File "/home/vscode/.local/lib/python3.8/site-packages/django/core/handlers/base.py", line 150, in get_response_async
    response = await self._middleware_chain(request)
TypeError: object HttpResponse can't be used in 'await' expression
HTTP GET /favicon.ico 500 [0.90, 127.0.0.1:41256]
1 Answers

Well, I'm still looking for a solution. But, after some research, I've found that there is an issue with the get_asgi_application.

I've read that the HTTP protocol is added by default by Django and for that reason, we don't need this line. After I delete "http": get_asgi_application(), the website started to work well.

There is a person talking about this here: https://djangokatya.wordpress.com/2020/10/26/500-internal-server-error-daphne-http-processing-error/

Anyway, on Channels' V3 documentation they ask explicitly to add "http": get_asgi_application(),... Don't know how it works without it, but it does for me.

The issue is: after this, I started to get an error in Daphne: ValueError: HTTP response has not yet been started but got http.response.body. Can't understand well what is happening up to now.

Related