summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHasan Ramezani <hasan.r67@gmail.com>2020-06-09 21:55:49 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-06-10 09:23:33 +0200
commita59de6e89e8dc1f3e71c9a5a5bbceb373ea5247e (patch)
tree4af5159c39ab39b8659a946f3bd6a1cab3ae5e6a
parent69a78a4a63ca70f77d2d6003bb6b563cc6dbab34 (diff)
Fixed #31675 -- Added warning to ExceptionReporter when exception chain has a cycle.
-rw-r--r--django/views/debug.py10
-rw-r--r--tests/view_tests/tests/test_debug.py11
2 files changed, 18 insertions, 3 deletions
diff --git a/django/views/debug.py b/django/views/debug.py
index bc95cbf6b0..c85b86c913 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -2,6 +2,7 @@ import functools
import re
import sys
import types
+import warnings
from pathlib import Path
from django.conf import settings
@@ -28,6 +29,10 @@ DEBUG_ENGINE = Engine(
CURRENT_DIR = Path(__file__).parent
+class ExceptionCycleWarning(UserWarning):
+ pass
+
+
class CallableSettingWrapper:
"""
Object to wrap callable appearing in settings.
@@ -401,6 +406,11 @@ class ExceptionReporter:
exceptions.append(exc_value)
exc_value = explicit_or_implicit_cause(exc_value)
if exc_value in exceptions:
+ warnings.warn(
+ "Cycle in the exception chain detected: exception '%s' "
+ "encountered again." % exc_value,
+ ExceptionCycleWarning,
+ )
# Avoid infinite loop if there's a cyclic reference (#29393).
break
diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py
index a305b77a1b..c3ae2cc600 100644
--- a/tests/view_tests/tests/test_debug.py
+++ b/tests/view_tests/tests/test_debug.py
@@ -23,8 +23,8 @@ from django.utils.functional import SimpleLazyObject
from django.utils.regex_helper import _lazy_re_compile
from django.utils.safestring import mark_safe
from django.views.debug import (
- CallableSettingWrapper, ExceptionReporter, Path as DebugPath,
- SafeExceptionReporterFilter, default_urlconf,
+ CallableSettingWrapper, ExceptionCycleWarning, ExceptionReporter,
+ Path as DebugPath, SafeExceptionReporterFilter, default_urlconf,
get_default_exception_reporter_filter, technical_404_response,
technical_500_response,
)
@@ -518,7 +518,12 @@ class ExceptionReporterTests(SimpleTestCase):
tb_frames = None
tb_generator = threading.Thread(target=generate_traceback_frames, daemon=True)
- tb_generator.start()
+ msg = (
+ "Cycle in the exception chain detected: exception 'inner' "
+ "encountered again."
+ )
+ with self.assertWarnsMessage(ExceptionCycleWarning, msg):
+ tb_generator.start()
tb_generator.join(timeout=5)
if tb_generator.is_alive():
# tb_generator is a daemon that runs until the main thread/process