Fixed #30318 -- Added check for importability of arguments of custom error handler views.

Thanks to Jon on Stack Overflow for reporting the issue.
This commit is contained in:
Alasdair Nicol 2019-04-04 00:17:25 +01:00 committed by Mariusz Felisiak
parent fc9566d42d
commit a5accc0368
5 changed files with 44 additions and 2 deletions

View File

@ -15,7 +15,7 @@ from urllib.parse import quote
from django.conf import settings
from django.core.checks import Error, Warning
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.functional import cached_property
from django.utils.http import RFC3986_SUBDELIMS, escape_leading_slashes
@ -405,7 +405,15 @@ class URLResolver:
# All handlers take (request, exception) arguments except handler500
# which takes (request).
for status_code, num_parameters in [(400, 2), (403, 2), (404, 2), (500, 1)]:
handler, param_dict = self.resolve_error_handler(status_code)
try:
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)
args = [None] * num_parameters
try:

View File

@ -473,6 +473,8 @@ The following checks are performed on your URL configuration:
end with a slash.
* **urls.E007**: The custom ``handlerXXX`` view ``'path.to.view'`` does not
take the correct number of arguments (…).
* **urls.E008**: The custom ``handlerXXX`` view ``'path.to.view'`` could not be
imported.
``contrib`` app checks
======================

View File

@ -46,3 +46,6 @@ Bugfixes
* Fixed a regression in Django 2.2 where
:class:`~django.contrib.postgres.search.SearchVector` generates SQL that is
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`).

View File

@ -181,6 +181,29 @@ class CheckCustomErrorHandlersTests(SimpleTestCase):
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')
def test_good_handlers(self):
result = check_url_config(None)

View File

@ -0,0 +1,6 @@
urlpatterns = []
handler400 = 'django.views.bad_handler'
handler403 = 'django.invalid_module.bad_handler'
handler404 = 'invalid_module.bad_handler'
handler500 = 'django'