Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/508.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix `__suppress_context__` not being respected in exception rendering
4 changes: 3 additions & 1 deletion src/cleo/ui/exception_trace/inspector.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ def __init__(self, exception: BaseException) -> None:
self._frames: FrameCollection | None = None
self._outer_frames = None
self._inner_frames = None
self._previous_exception = exception.__context__
self._previous_exception = (
None if exception.__suppress_context__ else exception.__context__
)

@property
def exception(self) -> BaseException:
Expand Down
6 changes: 6 additions & 0 deletions tests/fixtures/exceptions/raiser_with_suppressed_context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

def raiser_with_suppressed_context() -> None:
try:
raise ValueError("This error should be suppressed.")
except ValueError:
raise RuntimeError("This error should be displayed.") from None
42 changes: 36 additions & 6 deletions tests/ui/test_exception_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from cleo.ui.exception_trace.component import ExceptionTrace
from tests.fixtures.exceptions import nested1
from tests.fixtures.exceptions import nested2
from tests.fixtures.exceptions import raiser_with_suppressed_context
from tests.fixtures.exceptions import recursion
from tests.fixtures.exceptions import simple

Expand Down Expand Up @@ -50,7 +51,7 @@ def test_render_debug_better_error_message() -> None:

trace.render(io)

lineno = 47
lineno = 48
expected = f"""
Stack trace:

Expand Down Expand Up @@ -84,7 +85,7 @@ def test_render_debug_better_error_message_recursion_error() -> None:
except RecursionError as e:
trace = ExceptionTrace(e)

lineno = 83
lineno = 84
trace.render(io)

expected = rf"""^
Expand Down Expand Up @@ -131,7 +132,7 @@ def test_render_very_verbose_better_error_message() -> None:
expected = f"""
Stack trace:

1 {trace._get_relative_file_path(__file__)}:125 in \
1 {trace._get_relative_file_path(__file__)}:126 in \
test_render_very_verbose_better_error_message
simple.simple_exception()

Expand Down Expand Up @@ -183,7 +184,7 @@ def test_render_can_ignore_given_files() -> None:
trace.ignore_files_in(rf"^{re.escape(nested1.__file__)}$")
trace.render(io)

lineno = 180
lineno = 181
expected = f"""
Stack trace:

Expand Down Expand Up @@ -221,7 +222,7 @@ def test_render_shows_ignored_files_if_in_debug_mode() -> None:
trace.ignore_files_in(rf"^{re.escape(nested1.__file__)}$")

trace.render(io)
lineno = 218
lineno = 219
expected = f"""
Stack trace:

Expand Down Expand Up @@ -344,7 +345,7 @@ def test_simple_render_aborts_if_no_message() -> None:
trace = ExceptionTrace(e.value)

trace.render(io, simple=True)
lineno = 342
lineno = 343

expected = f"""
AssertionError
Expand All @@ -364,3 +365,32 @@ def test_simple_render_aborts_if_no_message() -> None:
{lineno + 4}│ trace.render(io, simple=True)
"""
assert expected == io.fetch_output()


def test_render_with_suppressed_context() -> None:
io = BufferedIO()
lineno = 6

# Arrange: Trigger and catch the exception
try:
raiser_with_suppressed_context.raiser_with_suppressed_context()
except Exception as e:
trace = ExceptionTrace(e)

trace.render(io)

expected = f"""\

RuntimeError

This error should be displayed.

at {trace._get_relative_file_path(raiser_with_suppressed_context.__file__)}:{lineno} in raiser_with_suppressed_context
{lineno - 4}│ def raiser_with_suppressed_context() -> None:
{lineno - 3}│ try:
{lineno - 2}│ raise ValueError("This error should be suppressed.")
{lineno - 1}│ except ValueError:
→ {lineno + 0}│ raise RuntimeError("This error should be displayed.") from None
{lineno + 1}│
"""
assert expected == io.fetch_output()
Loading