Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decrease default errors verbosity #132

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion cleo/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,8 @@ def render_error(self, error: Exception, io: IO) -> None:
trace = ExceptionTrace(
error, solution_provider_repository=self._solution_provider_repository
)
trace.render(io.error_output, isinstance(error, CleoSimpleException))
simple = not io.is_verbose() or isinstance(error, CleoSimpleException)
trace.render(io.error_output, simple)

def _configure_io(self, io: IO) -> None:
if io.input.has_parameter_option("--ansi", True):
Expand Down
14 changes: 6 additions & 8 deletions cleo/ui/exception_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from typing import TYPE_CHECKING

from crashtest.frame_collection import FrameCollection
from crashtest.inspector import Inspector

from cleo.formatters.formatter import Formatter

Expand Down Expand Up @@ -255,9 +254,10 @@ def render(self, io: IO | Output, simple: bool = False) -> None:
if simple:
io.write_line("")
io.write_line(f"<error>{str(self._exception)}</error>")
return
else:
self._render_exception(io, self._exception)

return self._render_exception(io, self._exception)
self._render_solution(io, self._exception)

def _render_exception(self, io: IO | Output, exception: Exception) -> None:
from crashtest.inspector import Inspector
Expand Down Expand Up @@ -286,8 +286,6 @@ def _render_exception(self, io: IO | Output, exception: Exception) -> None:
current_frame = inspector.frames[-1]
self._render_snippet(io, current_frame)

self._render_solution(io, inspector)

def _render_snippet(self, io: IO | Output, frame: Frame) -> None:
self._render_line(
io,
Expand All @@ -306,12 +304,12 @@ def _render_snippet(self, io: IO | Output, frame: Frame) -> None:
for code_line in code_lines:
self._render_line(io, code_line, indent=4)

def _render_solution(self, io: IO | Output, inspector: Inspector) -> None:
def _render_solution(self, io: IO | Output, exception: Exception) -> None:
if self._solution_provider_repository is None:
return

solutions = self._solution_provider_repository.get_solutions_for_exception(
inspector.exception
exception
)
symbol = "•"
if not io.supports_utf8():
Expand Down Expand Up @@ -348,7 +346,7 @@ def _render_trace(self, io: IO | Output, frames: FrameCollection) -> None:
stack_frames.append(frame)

remaining_frames_length = len(stack_frames) - 1
if io.is_verbose() and remaining_frames_length:
if io.is_very_verbose() and remaining_frames_length:
self._render_line(io, "<fg=yellow>Stack trace</>:", True)
max_frame_length = len(str(remaining_frames_length))
frame_collections = stack_frames.compact()
Expand Down
67 changes: 62 additions & 5 deletions tests/ui/test_exception_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ def test_render_debug_better_error_message_recursion_error():
assert re.match(expected, io.fetch_output()) is not None


def test_render_verbose_better_error_message():
def test_render_very_verbose_better_error_message():
io = BufferedIO()
io.set_verbosity(Verbosity.VERBOSE)
io.set_verbosity(Verbosity.VERY_VERBOSE)

try:
fail()
Expand All @@ -158,7 +158,7 @@ def test_render_verbose_better_error_message():
expected = r"""^
Stack trace:

1 {}:152 in test_render_verbose_better_error_message
1 {}:152 in test_render_very_verbose_better_error_message
fail\(\)

Exception
Expand Down Expand Up @@ -192,7 +192,7 @@ def second():

def test_render_debug_better_error_message_recursion_error_with_multiple_duplicated_frames():
io = BufferedIO()
io.set_verbosity(Verbosity.VERBOSE)
io.set_verbosity(Verbosity.VERY_VERBOSE)

with pytest.raises(RecursionError) as e:
first()
Expand All @@ -212,7 +212,7 @@ def test_render_can_ignore_given_files():
from tests.ui.helpers import outer

io = BufferedIO()
io.set_verbosity(Verbosity.VERBOSE)
io.set_verbosity(Verbosity.VERY_VERBOSE)

def call():
def run():
Expand Down Expand Up @@ -477,3 +477,60 @@ def test():
" ...",
"",
]


def test_simple_render():
io = BufferedIO()

with pytest.raises(Exception) as e:
fail()

trace = ExceptionTrace(e.value)

trace.render(io, simple=True)

expected = """
Failed
"""

assert expected == io.fetch_output()


def test_simple_render_supports_solutions():
from crashtest.contracts.base_solution import BaseSolution
from crashtest.contracts.provides_solution import ProvidesSolution
from crashtest.solution_providers.solution_provider_repository import (
SolutionProviderRepository,
)

class CustomError(ProvidesSolution, Exception):
@property
def solution(self):
solution = BaseSolution("Solution Title.", "Solution Description")
solution.documentation_links.append("https://example.com")
solution.documentation_links.append("https://example2.com")

return solution

io = BufferedIO()

def call():
raise CustomError("Error with solution")

with pytest.raises(CustomError) as e:
call()

trace = ExceptionTrace(
e.value, solution_provider_repository=SolutionProviderRepository()
)

trace.render(io, simple=True)

expected = """
Error with solution

• Solution Title: Solution Description
https://example.com,
https://example2.com
"""
assert expected == io.fetch_output()