Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/servicex_mcp/tools/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ def classify_error(exc: Exception) -> str:
specific recovery steps rather than a bare traceback string.
"""
exc_type = type(exc).__name__
exc_msg = str(exc)
# A bare exception (e.g. a ProxyClient redeem call raising a timeout with
# no message) has an empty str(exc) -- fall back to the type name so the
# caller sees *something* happened instead of a blank "Error: " message.
exc_msg = str(exc) or exc_type
msg_lower = exc_msg.lower()
type_lower = exc_type.lower()

Expand Down
13 changes: 13 additions & 0 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,24 @@ def test_timeout_error_by_type_name_with_no_matching_message(self) -> None:
assert "**Recovery:**" in result
assert "servicex_info" in result

def test_blank_message_falls_back_to_exception_type_name(self) -> None:
# A bare TimeoutError() (e.g. from a broker redeem call exceeding
# ProxyClient's timeout) has an empty str(exc); the displayed error
# must still say *something* happened, not "Error: \n\n**Recovery:**...".
result = classify_error(TimeoutError())
assert result.startswith("Error: TimeoutError")

def test_other_category_has_no_recovery_block(self) -> None:
result = classify_error(Exception("something completely unexpected"))
assert result == "Error: something completely unexpected"
assert "Recovery" not in result

def test_other_category_blank_message_falls_back_to_exception_type_name(
self,
) -> None:
result = classify_error(Exception())
assert result == "Error: Exception"

def test_proxy_not_available_error_category(self) -> None:
result = classify_error(ProxyNotAvailableError("no linked credential"))
assert result.startswith("Error: no linked credential")
Expand Down
Loading