[Django] #34998: Raising a StopIteration in asynchronous mode hangs the request

13 views
Skip to first unread message

Django

unread,
Nov 28, 2023, 8:21:57 AM11/28/23
to django-...@googlegroups.com
#34998: Raising a StopIteration in asynchronous mode hangs the request
--------------------------------------------+------------------------
Reporter: Clément Escolano | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.2
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
--------------------------------------------+------------------------
When using Django in Asynchronous mode, if some code raises a
`StopIteration` error (generally when calling `next()` on an empty
generator), the request hangs. I think Django should handle the error
gracefully (display a 500 error page) instead.

Basically, when the code raises a `StopIteration` error, the following is
displayed and the request hangs:

{{{
TypeError: StopIteration interacts badly with generators and cannot be
raised into a Future
}}}

I have reproduce the issue with a minimal project here: https://github.com
/clement-escolano/django-stopiteration

Relevant file is `stopiteration/views.py` which is a view called on
`/error` endpoint and contains:

{{{
def error(request):
next(i for i in [])
return None
}}}

The Django application must be run with asynchronous support. For instance
with: `uvicorn test_stopiteration.asgi:application`.

--
Ticket URL: <https://code.djangoproject.com/ticket/34998>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Nov 28, 2023, 11:34:13 AM11/28/23
to django-...@googlegroups.com
#34998: Raising a StopIteration in asynchronous mode hangs the request
----------------------------------+--------------------------------------

Reporter: Clément Escolano | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.2
Severity: Normal | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Changes (by Mariusz Felisiak):

* cc: Carlton Gibson (added)


Comment:

Is it not a duplicate of #33795, #32798, or #33735?

--
Ticket URL: <https://code.djangoproject.com/ticket/34998#comment:1>

Django

unread,
Nov 28, 2023, 1:48:21 PM11/28/23
to django-...@googlegroups.com
#34998: Raising a StopIteration in asynchronous mode hangs the request
----------------------------------+--------------------------------------
Reporter: Clément Escolano | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------
Changes (by Carlton Gibson):

* cc: Andrew Godwin (added)


Comment:

Good issue. AFAICS this is https://github.com/python/cpython/issues/112182

See also https://github.com/agronholm/anyio/pull/477 and
https://github.com/tiangolo/fastapi/issues/966 — aynio was able to work
around it, but it's not clear we're going to be able to doing anything
pending a fix in asyncio.

To quote Guido from the Python issue:

> My first response is "don't do that". That's why it prints such an
elaborate warning.

Short of a concrete suggestion, 🤷‍♀️

--
Ticket URL: <https://code.djangoproject.com/ticket/34998#comment:2>

Django

unread,
Nov 28, 2023, 1:59:02 PM11/28/23
to django-...@googlegroups.com
#34998: Raising a StopIteration in asynchronous mode hangs the request
----------------------------------+--------------------------------------
Reporter: Clément Escolano | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------+--------------------------------------

Comment (by Andrew Godwin):

Hmm yes, this is one of those nasty bugs that reveals the true nature of
how Python async works.

In testing this locally with just plain async functions, I don't see how
we can catch this - the error happens when you return StopIteration from
_any_ awaited function, you can't wrap around it to catch it instead.
Given that views are always going to be async functions, unless we want to
wrap every single view, decorator and middleware in our own custom Future
it's not going to be reasonable to catch it.

--
Ticket URL: <https://code.djangoproject.com/ticket/34998#comment:3>

Django

unread,
Nov 28, 2023, 2:02:52 PM11/28/23
to django-...@googlegroups.com
#34998: Raising a StopIteration in asynchronous mode hangs the request
-------------------------------------+-------------------------------------

Reporter: Clément Escolano | Owner: nobody
Type: | Status: closed
Cleanup/optimization |
Component: Core (Other) | Version: 4.2
Severity: Normal | Resolution: wontfix

Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => wontfix
* component: Uncategorized => Core (Other)
* type: Uncategorized => Cleanup/optimization


Comment:

Thanks for comments!

Closing as "wontfix" unless someone can prove it's actionable in Django
itself.

--
Ticket URL: <https://code.djangoproject.com/ticket/34998#comment:4>

Reply all
Reply to author
Forward
0 new messages