Skip to content

Consolidate error classification for realtime WebSocket failures#107

Merged
alexkroman merged 2 commits into
mainfrom
claude/eloquent-hamilton-fqvnpt
Jun 12, 2026
Merged

Consolidate error classification for realtime WebSocket failures#107
alexkroman merged 2 commits into
mainfrom
claude/eloquent-hamilton-fqvnpt

Conversation

@alexkroman

Copy link
Copy Markdown
Collaborator

Summary

Refactors error handling across realtime streaming paths (agent, TTS, and client streaming) to use a single shared error classification function, eliminating duplication and ensuring consistent error messages and suggestions across all WebSocket connection failures.

Key Changes

  • New classify_error() function in aai_cli/streaming/diagnostics.py: Centralizes the logic for mapping WebSocket failures to appropriate CLIError types. Handles both rejected handshakes (HTTP 401/403) with actionable suggestions and other failures via the wsutil mapping.

  • Refactored import_sounddevice() in aai_cli/microphone.py: Extracted lazy import logic into a public function with clear documentation. This is now the single import-and-fail path for all audio device operations (mic capture, TTS playback, agent duplex stream), ensuring consistent error handling.

  • Updated WebSocket error handlers in aai_cli/tts/session.py, aai_cli/agent/session.py, and aai_cli/client.py: Replaced inline error classification logic with calls to classify_error(), reducing code duplication and ensuring all paths handle handshake rejections identically.

  • Simplified audio imports in aai_cli/agent/audio.py and aai_cli/tts/audio.py: Replaced try/except blocks with direct calls to import_sounddevice(), leveraging the centralized error handling.

  • Type signature improvements in aai_cli/ws.py: Changed is_rejected_key() and auth_or_api_error() to accept object instead of Exception, improving type flexibility for error classification.

Implementation Details

The refactoring ensures that:

  • A rejected handshake (HTTP 401/403) always gets the shared actionable suggestion (whoami / environment / network)
  • Other connection failures consistently use the wsutil mapping (rejected key → auth_failure(), rest → APIError)
  • All three realtime paths (stream, agent, TTS) follow the same error classification logic
  • Audio device initialization failures are consistently handled across all audio operations

https://claude.ai/code/session_017LGjFkWANGnCZmgHDHWM7E

Three modules (tts/session, agent/session, client) each carried their own
copy of the same failure classification: try diagnostics.handshake_error
for a rejected handshake (HTTP 401/403), else fall back to the rejected-
key/API mapping. Collapse them onto one diagnostics.classify_error so the
realtime paths (stream, agent, speak) can't drift apart; ws.is_rejected_key
and ws.auth_or_api_error widen to `object` to admit the stream path's
recorded Error events (errors.is_auth_failure already took object).

Likewise the lazy `import sounddevice` with its ImportError ->
audio_missing_error mapping was copy-pasted in microphone, tts/audio, and
agent/audio; it now lives once as microphone.import_sounddevice.

No behavior change: the handshake fallback in client ran with a None
handshake status, where is_rejected_key reduces to is_auth_failure.

https://claude.ai/code/session_017LGjFkWANGnCZmgHDHWM7E
@alexkroman alexkroman enabled auto-merge (squash) June 12, 2026 13:33
@alexkroman alexkroman merged commit 438a194 into main Jun 12, 2026
16 checks passed
@alexkroman alexkroman deleted the claude/eloquent-hamilton-fqvnpt branch June 12, 2026 13:39
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