Add per-event logging and top-level exception catching
All checks were successful
Build ROCm Image / build (push) Successful in 6m2s

Log every event type on arrival and wrap handle_event in try/except
so silent crashes are visible. Helps diagnose the streaming protocol
hang where no logs appear after supports_synthesize_streaming=True.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-05 17:10:32 -04:00
parent 3d3e8bdabf
commit 23a0b914fa

View File

@@ -63,6 +63,14 @@ class ChatterboxWyomingHandler(AsyncEventHandler):
self._streaming_voice: Optional[str] = None
async def handle_event(self, event: Event) -> bool:
logger.info(f"Event received: {event.type}")
try:
return await self._handle_event(event)
except Exception:
logger.exception(f"Unhandled exception in handle_event for {event.type}")
return True
async def _handle_event(self, event: Event) -> bool:
if Describe.is_type(event.type):
await self.write_event(self._info.event())
return True
@@ -72,6 +80,7 @@ class ChatterboxWyomingHandler(AsyncEventHandler):
self._streaming = True
self._streaming_text = ""
self._streaming_voice = start.voice.name if start.voice else None
logger.info(f"Streaming started, voice='{self._streaming_voice}'")
return True
if SynthesizeChunk.is_type(event.type):
@@ -81,6 +90,7 @@ class ChatterboxWyomingHandler(AsyncEventHandler):
return True
if SynthesizeStop.is_type(event.type):
logger.info(f"SynthesizeStop — text: {self._streaming_text!r}")
if self._streaming and self._streaming_text:
await self._synthesize_and_stream(
self._streaming_text,
@@ -95,14 +105,17 @@ class ChatterboxWyomingHandler(AsyncEventHandler):
if Synthesize.is_type(event.type):
if self._streaming:
# Ignore duplicate Synthesize events sent alongside streaming protocol
logger.info("Ignoring Synthesize (streaming protocol active)")
return True
synth = Synthesize.from_event(event)
voice_name = synth.voice.name if synth.voice else None
logger.info(f"Synthesize — voice='{voice_name}', text: {synth.text!r}")
await self._synthesize_and_stream(synth.text, voice_name)
# NOTE: SynthesizeStopped is NOT sent here — it belongs only to the
# streaming protocol (SynthesizeStop path). Sending it here confuses HA.
return True
logger.warning(f"Unhandled event type: {event.type}")
return True
async def _synthesize_and_stream(self, text: str, voice_name: Optional[str]) -> None: