[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:
Alasdair Nicol 2019-04-04 00:17:25 +01:00 committed by Mariusz Felisiak
parent f24cf51661
commit 3c3df7db8e
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

@ -464,6 +464,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'