django-commons / django-debug-toolbar

A configurable set of panels that display various debug information about the current request/response.
https://django-debug-toolbar.readthedocs.io
BSD 3-Clause "New" or "Revised" License
8.08k stars 1.05k forks source link

AttributeError: This StreamingHttpResponse instance has no `content` attribute. Use `streaming_content` instead. #1945

Closed danjac closed 3 months ago

danjac commented 3 months ago

This appears to happen when returning a FileResponse. The issue looks like a regression in 4.4.3.

django==5.0.6
django-debug-toolbar==4.4.3
File "/my-project/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 140, in response_for_exception
    response = handle_uncaught_exception(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/my-project/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 181, in handle_uncaught_exception
    return debug.technical_500_response(request, *exc_info)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/my-project/.venv/lib/python3.12/site-packages/django_extensions/management/technical_response.py", line 41, in null_technical_500_response
    raise exc_value
  File "/my-project/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/my-project/.venv/lib/python3.12/site-packages/debug_toolbar/middleware.py", line 94, in __call__
    panel.generate_stats(request, response)
  File "/my-project/.venv/lib/python3.12/site-packages/debug_toolbar/panels/alerts.py", line 142, in generate_stats
    html_content = response.content.decode(response.charset)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/my-project/.venv/lib/python3.12/site-packages/django/http/response.py", line 458, in content
    raise AttributeError(
AttributeError: This StreamingHttpResponse instance has no `content` attribute. Use `streaming_content` instead.
danjac commented 3 months ago

Downgrading to 4.4.2 fixes the issue.

matthiask commented 3 months ago

Thanks for the report. The new alerts panel should have a check for streaming responses. Do you want to submit a fix for this?

danjac commented 3 months ago

Not very familiar with the code but presumably a check needed here ?

https://github.com/jazzband/django-debug-toolbar/blob/main/debug_toolbar/panels/alerts.py#L142

def generate_stats(self, request, response):
        html_content = response.content.decode(response.charset)
matthiask commented 3 months ago

I wondered for a moment what's going on since we are already checking for streaming responses, but that's only when we check if we should insert the toolbar's HTML, not when generating the stats.

https://github.com/jazzband/django-debug-toolbar/blob/c79f249aa9955fb6be2d4363947406ea13d12155/debug_toolbar/middleware.py#L107-L112

So yes, the generate_stats method should probably have similar checks as well and not process streaming responses at all.

I think we would want a unit test for this as well since we didn't catch this problem in time.

tim-schilling commented 3 months ago

I wonder if we should do something like we're doing with async and have a streaming compatible attribute on the panels that prevents the panel from attempting to process these responses.