Opened 3 years ago
Last modified 2 years ago
#34451 assigned Bug
Incorrect handling of ImproperlyConfigured Exception in views in ASGI context — at Version 2
| Reported by: | Michael Galler | Owned by: | nobody |
|---|---|---|---|
| Component: | Error reporting | Version: | 4.1 |
| Severity: | Normal | Keywords: | |
| Cc: | asgi | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
start with
django-admin startproject myproject
views.py
from django.views.generic import FormView
class TestView(FormView):
async def post(self, request, *args, **kwargs):
return 'Foobar'
urls.py
from django.contrib import admin
from django.urls import path
from myproject.views import TestView
urlpatterns = [
path('admin/', admin.site.urls),
path('test/', TestView.as_view()),
]
This should raise
django.core.exceptions.ImproperlyConfigured: TestView HTTP handlers must either be all sync or all async.
Running the devserver via manage.py results in
C:\code\myproject\venv\Scripts\python.exe C:\code\myproject\manage.py runserver 8000
Performing system checks...
Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
File "C:\Program Files\Python311\Lib\threading.py", line 1038, in _bootstrap_inner
self.run()
File "C:\Program Files\Python311\Lib\threading.py", line 975, in run
self._target(*self._args, **self._kwargs)
File "C:\code\myproject\venv\Lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "C:\code\myproject\venv\Lib\site-packages\django\core\management\commands\runserver.py", line 134, in inner_run
self.check(display_num_errors=True)
File "C:\code\myproject\venv\Lib\site-packages\django\core\management\base.py", line 475, in check
all_issues = checks.run_checks(
^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
new_errors = check(app_configs=app_configs, databases=databases)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\checks\urls.py", line 14, in check_url_config
return check_resolver(resolver)
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\checks\urls.py", line 24, in check_resolver
return check_method()
^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 494, in check
for pattern in self.url_patterns:
^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 715, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 708, in urlconf_module
return import_module(self.urlconf_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "C:\code\myproject\myproject\urls.py", line 8, in <module>
path('test/', TestView.as_view()),
^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\generic\base.py", line 119, in as_view
if cls.view_is_async:
^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 71, in __get__
return self.fget(cls)
^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\generic\base.py", line 73, in view_is_async
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: TestView HTTP handlers must either be all sync or all async.
Now the same thing with hypercorn will result in some sort of recursion that I do not understand.
Uvicorn behaves the same way.
(venv) λ hypercorn myproject.asgi:application
[2023-03-31 11:54:00 +0200] [16000] [WARNING] ASGI Framework Lifespan error, continuing without Lifespan support
[2023-03-31 11:54:00 +0200] [16000] [INFO] Running on http://127.0.0.1:8000 (CTRL + C to quit)
[2023-03-31 11:54:08 +0200] [16000] [ERROR] Error in ASGI Framework
Traceback (most recent call last):
File "C:\code\myproject\venv\Lib\site-packages\asgiref\sync.py", line 486, in thread_handler
raise exc_info[1]
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\exception.py", line 43, in inner
response = await get_response(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\base.py", line 235, in _get_response_async
callback, callback_args, callback_kwargs = self.resolve_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\base.py", line 313, in resolve_request
resolver_match = resolver.resolve(request.path_info)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 663, in resolve
for pattern in self.url_patterns:
^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 715, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 708, in urlconf_module
return import_module(self.urlconf_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "C:\code\myproject\myproject\urls.py", line 8, in <module>
path('test/', TestView.as_view()),
^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\generic\base.py", line 119, in as_view
if cls.view_is_async:
^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 71, in __get__
return self.fget(cls)
^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\generic\base.py", line 73, in view_is_async
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: TestView HTTP handlers must either be all sync or all async.
During handling of the above exception, another exception occurred:
... (the same frame over and over again)
In my personal project this leads to a strange problem with django-ninja
api.py
from ninja import NinjaAPI api = NinjaAPI()
urls.py
from django.contrib import admin
from django.urls import path
from myproject.api import api
from myproject.views import TestView
urlpatterns = [
path('admin/', admin.site.urls),
path("api/", api.urls),
path('test/', TestView.as_view()),
]
manage.py devserver:
C:\code\myproject\venv\Scripts\python.exe C:\code\myproject\manage.py runserver 8000
Watching for file changes with StatReloader
Performing system checks...
Exception in thread django-main-thread:
Traceback (most recent call last):
File "C:\Program Files\Python311\Lib\threading.py", line 1038, in _bootstrap_inner
self.run()
File "C:\Program Files\Python311\Lib\threading.py", line 975, in run
self._target(*self._args, **self._kwargs)
File "C:\code\myproject\venv\Lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "C:\code\myproject\venv\Lib\site-packages\django\core\management\commands\runserver.py", line 134, in inner_run
self.check(display_num_errors=True)
File "C:\code\myproject\venv\Lib\site-packages\django\core\management\base.py", line 475, in check
all_issues = checks.run_checks(
^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
new_errors = check(app_configs=app_configs, databases=databases)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\checks\urls.py", line 14, in check_url_config
return check_resolver(resolver)
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\checks\urls.py", line 24, in check_resolver
return check_method()
^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 494, in check
for pattern in self.url_patterns:
^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 715, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 708, in urlconf_module
return import_module(self.urlconf_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "C:\code\myproject\myproject\urls.py", line 10, in <module>
path('test/', TestView.as_view()),
^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\generic\base.py", line 119, in as_view
if cls.view_is_async:
^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 71, in __get__
return self.fget(cls)
^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\generic\base.py", line 73, in view_is_async
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: TestView HTTP handlers must either be all sync or all async.
With hypercorn:
(venv) λ hypercorn myproject.asgi:application
[2023-03-31 12:03:33 +0200] [20028] [WARNING] ASGI Framework Lifespan error, continuing without Lifespan support
[2023-03-31 12:03:33 +0200] [20028] [INFO] Running on http://127.0.0.1:8000 (CTRL + C to quit)
[2023-03-31 12:03:40 +0200] [20028] [ERROR] Error in ASGI Framework
Traceback (most recent call last):
File "C:\code\myproject\venv\Lib\site-packages\asgiref\sync.py", line 486, in thread_handler
raise exc_info[1]
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\exception.py", line 43, in inner
response = await get_response(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\base.py", line 235, in _get_response_async
callback, callback_args, callback_kwargs = self.resolve_request(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\base.py", line 313, in resolve_request
resolver_match = resolver.resolve(request.path_info)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 663, in resolve
for pattern in self.url_patterns:
^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 715, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 708, in urlconf_module
return import_module(self.urlconf_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "C:\code\myproject\myproject\urls.py", line 10, in <module>
path('test/', TestView.as_view()),
^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\generic\base.py", line 119, in as_view
if cls.view_is_async:
^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 71, in __get__
return self.fget(cls)
^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\generic\base.py", line 73, in view_is_async
raise ImproperlyConfigured(
django.core.exceptions.ImproperlyConfigured: TestView HTTP handlers must either be all sync or all async.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\code\myproject\venv\Lib\site-packages\asgiref\sync.py", line 486, in thread_handler
raise exc_info[1]
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\exception.py", line 43, in inner
response = await get_response(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\deprecation.py", line 152, in __acall__
response = response or await self.get_response(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\exception.py", line 45, in inner
response = await sync_to_async(
^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\asgiref\sync.py", line 448, in __call__
ret = await asyncio.wait_for(future, timeout=None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\asyncio\tasks.py", line 442, in wait_for
return await fut
^^^^^^^^^
File "C:\Program Files\Python311\Lib\concurrent\futures\thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\asgiref\sync.py", line 488, in thread_handler
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\exception.py", line 141, in response_for_exception
response = handle_uncaught_exception(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\core\handlers\exception.py", line 182, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\debug.py", line 66, in technical_500_response
html = reporter.get_traceback_html()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\debug.py", line 396, in get_traceback_html
c = Context(self.get_traceback_data(), use_l10n=False)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\debug.py", line 381, in get_traceback_data
c["raising_view_name"] = get_caller(self.request)
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\views\debug.py", line 99, in get_caller
resolver_match = resolve(request.path)
^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\base.py", line 24, in resolve
return get_resolver(urlconf).resolve(path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 663, in resolve
for pattern in self.url_patterns:
^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 715, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\utils\functional.py", line 57, in __get__
res = instance.__dict__[self.name] = self.func(instance)
^^^^^^^^^^^^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\django\urls\resolvers.py", line 708, in urlconf_module
return import_module(self.urlconf_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\Python311\Lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1206, in _gcd_import
File "<frozen importlib._bootstrap>", line 1178, in _find_and_load
File "<frozen importlib._bootstrap>", line 1149, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 940, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "C:\code\myproject\myproject\urls.py", line 9, in <module>
path("api/", api.urls),
^^^^^^^^
File "C:\code\myproject\venv\Lib\site-packages\ninja\main.py", line 379, in urls
self._validate()
File "C:\code\myproject\venv\Lib\site-packages\ninja\main.py", line 494, in _validate
raise ConfigError(msg.strip())
ninja.errors.ConfigError: Looks like you created multiple NinjaAPIs or TestClients
To let ninja distinguish them you need to set either unique version or urls_namespace
- NinjaAPI(..., version='2.0.0')
- NinjaAPI(..., urls_namespace='otherapi')
Already registered: ['api-1.0.0']
During handling of the above exception, another exception occurred:
... (the same frame over and over again)
Change History (2)
comment:1 by , 3 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 3 years ago
| Description: | modified (diff) |
|---|
Note:
See TracTickets
for help on using tickets.