mirror of https://github.com/django/django.git
Fixed #31675 -- Added warning to ExceptionReporter when exception chain has a cycle.
This commit is contained in:
parent
69a78a4a63
commit
a59de6e89e
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue