diff options
| author | Hasan Ramezani <hasan.r67@gmail.com> | 2020-06-09 21:55:49 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-06-10 09:23:33 +0200 |
| commit | a59de6e89e8dc1f3e71c9a5a5bbceb373ea5247e (patch) | |
| tree | 4af5159c39ab39b8659a946f3bd6a1cab3ae5e6a | |
| parent | 69a78a4a63ca70f77d2d6003bb6b563cc6dbab34 (diff) | |
Fixed #31675 -- Added warning to ExceptionReporter when exception chain has a cycle.
| -rw-r--r-- | django/views/debug.py | 10 | ||||
| -rw-r--r-- | tests/view_tests/tests/test_debug.py | 11 |
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 |
