[2.2.x] Fixed #30318 -- Added check for importability of arguments of custom error handler views.
Thanks to Jon on Stack Overflow for reporting the issue.
Backport of a5accc0368
from master
This commit is contained in:
parent
f24cf51661
commit
3c3df7db8e
|
@ -15,7 +15,7 @@ from urllib.parse import quote
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.checks import Error, Warning
|
from django.core.checks import Error, Warning
|
||||||
from django.core.checks.urls import check_resolver
|
from django.core.checks.urls import check_resolver
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
|
||||||
from django.utils.datastructures import MultiValueDict
|
from django.utils.datastructures import MultiValueDict
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.http import RFC3986_SUBDELIMS, escape_leading_slashes
|
from django.utils.http import RFC3986_SUBDELIMS, escape_leading_slashes
|
||||||
|
@ -405,7 +405,15 @@ class URLResolver:
|
||||||
# All handlers take (request, exception) arguments except handler500
|
# All handlers take (request, exception) arguments except handler500
|
||||||
# which takes (request).
|
# which takes (request).
|
||||||
for status_code, num_parameters in [(400, 2), (403, 2), (404, 2), (500, 1)]:
|
for status_code, num_parameters in [(400, 2), (403, 2), (404, 2), (500, 1)]:
|
||||||
|
try:
|
||||||
handler, param_dict = self.resolve_error_handler(status_code)
|
handler, param_dict = self.resolve_error_handler(status_code)
|
||||||
|
except (ImportError, ViewDoesNotExist) as e:
|
||||||
|
path = getattr(self.urlconf_module, 'handler%s' % status_code)
|
||||||
|
msg = (
|
||||||
|
"The custom handler{status_code} view '{path}' could not be imported."
|
||||||
|
).format(status_code=status_code, path=path)
|
||||||
|
messages.append(Error(msg, hint=str(e), id='urls.E008'))
|
||||||
|
continue
|
||||||
signature = inspect.signature(handler)
|
signature = inspect.signature(handler)
|
||||||
args = [None] * num_parameters
|
args = [None] * num_parameters
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -464,6 +464,8 @@ The following checks are performed on your URL configuration:
|
||||||
end with a slash.
|
end with a slash.
|
||||||
* **urls.E007**: The custom ``handlerXXX`` view ``'path.to.view'`` does not
|
* **urls.E007**: The custom ``handlerXXX`` view ``'path.to.view'`` does not
|
||||||
take the correct number of arguments (…).
|
take the correct number of arguments (…).
|
||||||
|
* **urls.E008**: The custom ``handlerXXX`` view ``'path.to.view'`` could not be
|
||||||
|
imported.
|
||||||
|
|
||||||
``contrib`` app checks
|
``contrib`` app checks
|
||||||
======================
|
======================
|
||||||
|
|
|
@ -46,3 +46,6 @@ Bugfixes
|
||||||
* Fixed a regression in Django 2.2 where
|
* Fixed a regression in Django 2.2 where
|
||||||
:class:`~django.contrib.postgres.search.SearchVector` generates SQL that is
|
:class:`~django.contrib.postgres.search.SearchVector` generates SQL that is
|
||||||
not indexable (:ticket:`30385`).
|
not indexable (:ticket:`30385`).
|
||||||
|
|
||||||
|
* Fixed a regression in Django 2.2 that caused an exception to be raised when
|
||||||
|
a custom error handler could not be imported (:ticket:`30318`).
|
||||||
|
|
|
@ -181,6 +181,29 @@ class CheckCustomErrorHandlersTests(SimpleTestCase):
|
||||||
id='urls.E007',
|
id='urls.E007',
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@override_settings(ROOT_URLCONF='check_framework.urls.bad_error_handlers_invalid_path')
|
||||||
|
def test_bad_handlers_invalid_path(self):
|
||||||
|
result = check_url_config(None)
|
||||||
|
paths = [
|
||||||
|
'django.views.bad_handler',
|
||||||
|
'django.invalid_module.bad_handler',
|
||||||
|
'invalid_module.bad_handler',
|
||||||
|
'django',
|
||||||
|
]
|
||||||
|
hints = [
|
||||||
|
"Could not import '{}'. View does not exist in module django.views.",
|
||||||
|
"Could not import '{}'. Parent module django.invalid_module does not exist.",
|
||||||
|
"No module named 'invalid_module'",
|
||||||
|
"Could not import '{}'. The path must be fully qualified.",
|
||||||
|
]
|
||||||
|
for code, path, hint, error in zip([400, 403, 404, 500], paths, hints, result):
|
||||||
|
with self.subTest('handler{}'.format(code)):
|
||||||
|
self.assertEqual(error, Error(
|
||||||
|
"The custom handler{} view '{}' could not be imported.".format(code, path),
|
||||||
|
hint=hint.format(path),
|
||||||
|
id='urls.E008',
|
||||||
|
))
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='check_framework.urls.good_error_handlers')
|
@override_settings(ROOT_URLCONF='check_framework.urls.good_error_handlers')
|
||||||
def test_good_handlers(self):
|
def test_good_handlers(self):
|
||||||
result = check_url_config(None)
|
result = check_url_config(None)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
urlpatterns = []
|
||||||
|
|
||||||
|
handler400 = 'django.views.bad_handler'
|
||||||
|
handler403 = 'django.invalid_module.bad_handler'
|
||||||
|
handler404 = 'invalid_module.bad_handler'
|
||||||
|
handler500 = 'django'
|
Loading…
Reference in New Issue