#34998 closed Cleanup/optimization (wontfix)

Raising a StopIteration in asynchronous mode hangs the request

Reported by: Clément Escolano Owned by: nobody
Component: Core (Other) Version: 4.2
Severity: Normal Keywords:
Cc: Carlton Gibson, Andrew Godwin Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

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.

Change History (4)

comment:1 by Mariusz Felisiak, 13 months ago

Cc: Carlton Gibson added

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

comment:2 by Carlton Gibson, 13 months ago

Cc: Andrew Godwin added

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, 🤷‍♀️

comment:3 by Andrew Godwin, 13 months ago

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.

comment:4 by Mariusz Felisiak, 13 months ago

Component: UncategorizedCore (Other)
Resolution: wontfix
Status: newclosed
Type: UncategorizedCleanup/optimization

Thanks for comments!

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

Note: See TracTickets for help on using tickets.
Back to Top