mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-30 06:41:51 +00:00
Remove unused imports (F401) and duplicate/shadowed import redefinitions (F811) across the codebase using ruff's safe autofixes. No behavioral changes -- imports only. - ~1400 safe autofixes applied across 644 files (net -1072 lines) - __init__.py re-exports preserved (excluded from F401 removal so public re-export surfaces stay intact) - Re-exports that are imported or monkeypatched by tests but look unused in their defining module are kept with explicit # noqa: F401 (gateway/run.py load_dotenv; run_agent re-exports from agent.message_sanitization, agent.context_compressor, agent.retry_utils, agent.prompt_builder, agent.process_bootstrap, agent.codex_responses_adapter) - Unsafe F841 (unused-variable) fixes deliberately skipped -- those can change behavior when the RHS has side effects - ruff lints remain disabled in pyproject.toml (only PLW1514 is selected); this is a one-time cleanup, not a config change Verification: - python -m compileall: clean - pytest --collect-only: all 27161 tests collect (zero import errors) - core entry points import clean (run_agent, model_tools, cli, toolsets, hermes_state, batch_runner, gateway) - static scan: every name any test imports directly from an edited module still resolves
85 lines
2.8 KiB
Python
85 lines
2.8 KiB
Python
"""Regression tests for MCP error messages when str(exc) is empty.
|
|
|
|
Issue #19417: ClosedResourceError (and similar exceptions raised without a
|
|
message argument) produced ``MCP call failed: ClosedResourceError: `` with
|
|
nothing after the colon, making debugging impossible.
|
|
|
|
Fix: ``_exc_str()`` falls back to ``repr(exc)`` when ``str(exc)`` is empty.
|
|
"""
|
|
|
|
|
|
|
|
from tools.mcp_tool import _exc_str, _sanitize_error
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# _exc_str unit tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class _EmptyMessageError(Exception):
|
|
"""Exception whose __str__ returns empty string (like anyio.ClosedResourceError)."""
|
|
|
|
def __str__(self):
|
|
return ""
|
|
|
|
|
|
class _NormalError(Exception):
|
|
pass
|
|
|
|
|
|
def test_exc_str_returns_str_when_nonempty():
|
|
exc = _NormalError("something broke")
|
|
assert _exc_str(exc) == "something broke"
|
|
|
|
|
|
def test_exc_str_falls_back_to_repr_when_str_empty():
|
|
exc = _EmptyMessageError()
|
|
result = _exc_str(exc)
|
|
assert result != ""
|
|
assert "_EmptyMessageError" in result
|
|
|
|
|
|
def test_exc_str_falls_back_to_repr_for_whitespace_only():
|
|
"""str(exc) that is only whitespace should also trigger the repr fallback."""
|
|
exc = Exception(" ")
|
|
result = _exc_str(exc)
|
|
# After strip(), the text is empty, so repr is used
|
|
assert result.strip() != ""
|
|
|
|
|
|
def test_exc_str_handles_closedresource_like_exception():
|
|
"""Simulate anyio.ClosedResourceError which has no message."""
|
|
# Replicate the real anyio.ClosedResourceError behavior
|
|
exc = type("ClosedResourceError", (Exception,), {"__str__": lambda self: ""})()
|
|
result = _exc_str(exc)
|
|
assert "ClosedResourceError" in result
|
|
assert result != ""
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Integration: error message format in _sanitize_error
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def test_error_message_not_empty_when_exc_has_no_message():
|
|
"""The formatted error string should always contain the exception class name."""
|
|
exc = _EmptyMessageError()
|
|
error_msg = _sanitize_error(
|
|
f"MCP call failed: {type(exc).__name__}: {_exc_str(exc)}"
|
|
)
|
|
assert "ClosedResourceError" not in error_msg or "_EmptyMessageError" in error_msg
|
|
# The key invariant: the message must not end with ": "
|
|
assert not error_msg.endswith(": ")
|
|
# And it must contain the exception type name
|
|
assert "_EmptyMessageError" in error_msg
|
|
|
|
|
|
def test_error_message_preserves_normal_exception_text():
|
|
"""Normal exceptions should still show their message text."""
|
|
exc = _NormalError("connection refused")
|
|
error_msg = _sanitize_error(
|
|
f"MCP call failed: {type(exc).__name__}: {_exc_str(exc)}"
|
|
)
|
|
assert "connection refused" in error_msg
|
|
assert "_NormalError" in error_msg
|