Skip to content

Commit

Permalink
[2.2.x] Fixed #30318 -- Added check for importability of arguments of…
Browse files Browse the repository at this point in the history
… custom error handler views.

Thanks to Jon on Stack Overflow for reporting the issue.

Backport of a5accc0 from master
  • Loading branch information
alasdairnicol authored and felixxm committed Apr 25, 2019
1 parent f24cf51 commit 3c3df7d
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 2 deletions.
12 changes: 10 additions & 2 deletions django/urls/resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
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
Expand Down Expand Up @@ -405,7 +405,15 @@ def _check_custom_error_handlers(self):
# 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:
Expand Down
2 changes: 2 additions & 0 deletions docs/ref/checks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
======================
Expand Down
3 changes: 3 additions & 0 deletions docs/releases/2.2.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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`).
23 changes: 23 additions & 0 deletions tests/check_framework/test_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,29 @@ def test_bad_handlers(self):
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)
Expand Down
6 changes: 6 additions & 0 deletions tests/check_framework/urls/bad_error_handlers_invalid_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
urlpatterns = []

handler400 = 'django.views.bad_handler'
handler403 = 'django.invalid_module.bad_handler'
handler404 = 'invalid_module.bad_handler'
handler500 = 'django'

0 comments on commit 3c3df7d

Please sign in to comment.