Skip to content

Conversation

@bokelley
Copy link
Contributor

Summary

Fixed error handling in MCP adapter to properly preserve original connection errors instead of masking them with cleanup exceptions. Added support for Python 3.11+ ExceptionGroup handling and fixed CancelledError leaking through from failed initialization.

Changes

  • Handle ExceptionGroup in cleanup (Python 3.11+) to extract real errors
  • Catch BaseException in connection loop to properly convert CancelledError
  • Log expected cleanup errors at debug level to reduce noise
  • Gracefully support Python 3.10 without BaseExceptionGroup

Test Plan

  • All 307 existing tests pass
  • New test verifies ExceptionGroup handling
  • CLI now correctly shows connection errors (e.g., 405) instead of cleanup noise

🤖 Generated with Claude Code

bokelley and others added 4 commits November 26, 2025 05:40
When an MCP connection fails, two issues were masking the real error:

1. Cleanup raises ExceptionGroup containing the HTTP error (Python 3.11+)
2. Session initialization raises CancelledError instead of the real error

This fix addresses both:

**ExceptionGroup handling:**
- Catch BaseException in cleanup to handle ExceptionGroup
- Extract and log individual exceptions from the group
- Gracefully handle Python 3.10 (no ExceptionGroup) and 3.11+
- Log HTTPStatusError at debug level (expected during cleanup)

**CancelledError handling:**
- Catch BaseException in connection loop (not just Exception)
- Properly convert CancelledError to ADCPConnectionError
- Preserve KeyboardInterrupt and SystemExit behavior

Now users see the actual connection error (e.g., "405 Method Not Allowed")
instead of confusing cleanup error messages.

Added test to verify ExceptionGroup handling works correctly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Addresses code review feedback to make error handling more robust:

1. Fix ExceptionGroup import - use built-in type directly, not from builtins
2. Add KeyboardInterrupt/SystemExit re-raise in cleanup path
3. Replace string-based HTTPStatusError check with isinstance
4. Update all references from BaseExceptionGroup to ExceptionGroup

These changes improve type safety, handle critical interrupts correctly,
and make the code more maintainable.

All tests pass and mypy type checking succeeds.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Ruff doesn't recognize sys.version_info guards for undefined names.
Changed to try/except pattern which both ruff and mypy accept.

Also removed unused sys import since we no longer need version checking.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The test_cleanup_handles_exception_group test uses ExceptionGroup
which doesn't exist in Python 3.10. Added skipif marker to skip
this test on Python < 3.11.

The functionality still works correctly in 3.10 (it gracefully handles
the absence of ExceptionGroup), we just can't test it directly since
we can't create an ExceptionGroup in the test.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bokelley bokelley merged commit 27ff0ae into main Nov 26, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants