test_error_before_breakpoint.py•13.8 kB
"""
Integration tests for error handling when exception occurs before breakpoint.
Tests that exceptions raised before reaching the breakpoint are captured
and returned as structured error responses.
"""
import pytest
import sys
from mcp_debug_tool.schemas import BreakpointRequest, StartSessionRequest
from mcp_debug_tool.sessions import SessionManager
@pytest.fixture
def workspace_root(tmp_path):
"""Create a temporary workspace."""
return tmp_path
@pytest.fixture
def session_manager(workspace_root):
"""Create a session manager."""
return SessionManager(workspace_root)
class TestErrorBeforeBreakpoint:
"""Integration tests for exceptions before breakpoint."""
def test_syntax_error_before_breakpoint(self, session_manager, workspace_root):
"""Test that syntax errors before breakpoint are captured."""
# Create a script with syntax error before breakpoint location
script_path = workspace_root / "syntax_error_script.py"
script_path.write_text("""x = 1
y = 2
# Line 3 - breakpoint requested here
z = { # Missing closing brace - syntax error
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=3,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify error is captured
assert response.hit is False
assert response.error is not None
assert response.error.type in ("SyntaxError", "IndentationError")
assert len(response.error.message) > 0
# Clean up
session_manager.end_session(session_id)
def test_runtime_error_before_breakpoint(
self, session_manager, workspace_root
):
"""Test that runtime errors before breakpoint are captured."""
# Create a script with runtime error before breakpoint
script_path = workspace_root / "runtime_error_script.py"
script_path.write_text("""x = 1
y = 0
z = x / y # ZeroDivisionError
# Line 4 - breakpoint requested here
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=4,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify error is captured
assert response.hit is False
assert response.error is not None
assert response.error.type == "ZeroDivisionError"
assert "division" in response.error.message.lower() or "zero" in response.error.message.lower()
# Clean up
session_manager.end_session(session_id)
def test_name_error_before_breakpoint(self, session_manager, workspace_root):
"""Test that NameError before breakpoint is captured."""
# Create a script with NameError
script_path = workspace_root / "name_error_script.py"
script_path.write_text("""x = 1
y = undefined_variable # NameError
# Line 3 - breakpoint requested here
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=3,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify error is captured
assert response.hit is False
assert response.error is not None
assert response.error.type == "NameError"
assert "undefined_variable" in response.error.message or "not defined" in response.error.message.lower()
# Clean up
session_manager.end_session(session_id)
def test_import_error_before_breakpoint(self, session_manager, workspace_root):
"""Test that ImportError before breakpoint is captured."""
# Create a script with import error
script_path = workspace_root / "import_error_script.py"
script_path.write_text("""import nonexistent_module # ImportError
x = 1
# Line 3 - breakpoint requested here
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=3,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify error is captured
assert response.hit is False
assert response.error is not None
assert response.error.type in ("ModuleNotFoundError", "ImportError")
assert "nonexistent_module" in response.error.message or "No module" in response.error.message
# Clean up
session_manager.end_session(session_id)
def test_assertion_error_before_breakpoint(
self, session_manager, workspace_root
):
"""Test that AssertionError before breakpoint is captured."""
# Create a script with assertion failure
script_path = workspace_root / "assertion_error_script.py"
script_path.write_text("""x = 1
assert x == 2, "x should be 2" # AssertionError
# Line 3 - breakpoint requested here
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=3,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify error is captured
assert response.hit is False
assert response.error is not None
assert response.error.type == "AssertionError"
assert "should be 2" in response.error.message or len(response.error.message) > 0
# Clean up
session_manager.end_session(session_id)
def test_error_traceback_is_captured(self, session_manager, workspace_root):
"""Test that error traceback is included in response."""
# Create a script with error
script_path = workspace_root / "traceback_script.py"
script_path.write_text("""def failing_function():
raise ValueError("Something went wrong")
failing_function()
# Line 5 - breakpoint requested here
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=5,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify error and traceback
assert response.hit is False
assert response.error is not None
assert response.error.type == "ValueError"
assert "Something went wrong" in response.error.message
# Traceback may or may not be present depending on implementation
if response.error.traceback:
assert "failing_function" in response.error.traceback or "traceback" in response.error.traceback.lower()
# Clean up
session_manager.end_session(session_id)
def test_type_error_before_breakpoint(self, session_manager, workspace_root):
"""Test that TypeError before breakpoint is captured."""
# Create a script with type error
script_path = workspace_root / "type_error_script.py"
script_path.write_text("""x = "string"
y = x + 5 # TypeError: can't concatenate str and int
# Line 3 - breakpoint requested here
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=3,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify error is captured
assert response.hit is False
assert response.error is not None
assert response.error.type == "TypeError"
# Clean up
session_manager.end_session(session_id)
def test_attribute_error_before_breakpoint(
self, session_manager, workspace_root
):
"""Test that AttributeError before breakpoint is captured."""
# Create a script with attribute error
script_path = workspace_root / "attribute_error_script.py"
script_path.write_text("""x = "string"
y = x.nonexistent_method() # AttributeError
# Line 3 - breakpoint requested here
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=3,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify error is captured
assert response.hit is False
assert response.error is not None
assert response.error.type == "AttributeError"
# Clean up
session_manager.end_session(session_id)
def test_index_error_before_breakpoint(self, session_manager, workspace_root):
"""Test that IndexError before breakpoint is captured."""
# Create a script with index error
script_path = workspace_root / "index_error_script.py"
script_path.write_text("""items = [1, 2, 3]
x = items[10] # IndexError
# Line 3 - breakpoint requested here
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=3,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify error is captured
assert response.hit is False
assert response.error is not None
assert response.error.type == "IndexError"
# Clean up
session_manager.end_session(session_id)
def test_error_response_structure(self, session_manager, workspace_root):
"""Test that error response has correct structure."""
# Create a script with error
script_path = workspace_root / "error_script.py"
script_path.write_text("""x = 1
y = 2
raise RuntimeError("Test error")
print("Done")
""")
# Create session
create_request = StartSessionRequest(
pythonPath=sys.executable,
entry=script_path.relative_to(workspace_root).as_posix()
)
create_response = session_manager.create_session(create_request)
session_id = create_response.sessionId
# Try to run to breakpoint on line 4 (after the error)
bp_request = BreakpointRequest(
file=script_path.relative_to(workspace_root).as_posix(),
line=4,
)
response = session_manager.run_to_breakpoint(session_id, bp_request)
# Verify response structure
assert hasattr(response, "hit")
assert hasattr(response, "error")
assert hasattr(response, "completed")
assert hasattr(response, "frameInfo")
assert response.hit is False # Should not reach line 4
assert response.error is not None
assert response.error.type == "RuntimeError"
assert "Test error" in response.error.message
# Clean up
session_manager.end_session(session_id)