From 6b38510ace66ea052f3110446527aa8176c613a0 Mon Sep 17 00:00:00 2001 From: Filipi Fuchter Date: Wed, 26 Nov 2025 12:03:52 -0300 Subject: [PATCH] Restoring to use yield ErrorFrame --- src/pipecat/services/aws/stt.py | 6 ++--- src/pipecat/services/aws/tts.py | 5 ++-- src/pipecat/services/azure/image.py | 4 +-- src/pipecat/services/azure/stt.py | 2 +- src/pipecat/services/azure/tts.py | 8 +++--- src/pipecat/services/cartesia/tts.py | 4 +-- src/pipecat/services/deepgram/flux/stt.py | 4 +-- src/pipecat/services/deepgram/tts.py | 4 +-- src/pipecat/services/elevenlabs/stt.py | 4 +-- src/pipecat/services/elevenlabs/tts.py | 10 +++---- src/pipecat/services/fal/image.py | 2 +- src/pipecat/services/fal/stt.py | 2 +- src/pipecat/services/fish/tts.py | 4 +-- src/pipecat/services/google/image.py | 4 +-- src/pipecat/services/google/tts.py | 6 +++-- src/pipecat/services/groq/tts.py | 2 +- src/pipecat/services/heygen/client.py | 32 +++++++++-------------- src/pipecat/services/lmnt/tts.py | 4 +-- src/pipecat/services/minimax/tts.py | 2 +- src/pipecat/services/moondream/vision.py | 2 +- src/pipecat/services/neuphonic/tts.py | 8 +++--- src/pipecat/services/openai/image.py | 2 +- src/pipecat/services/openai/tts.py | 2 +- src/pipecat/services/piper/tts.py | 4 +-- src/pipecat/services/playht/tts.py | 6 ++--- src/pipecat/services/rime/tts.py | 8 +++--- src/pipecat/services/riva/stt.py | 6 ++--- src/pipecat/services/riva/tts.py | 8 +----- src/pipecat/services/sarvam/tts.py | 4 +-- src/pipecat/services/speechmatics/stt.py | 2 +- src/pipecat/services/ultravox/stt.py | 6 ++--- src/pipecat/services/whisper/base_stt.py | 2 +- src/pipecat/services/whisper/stt.py | 4 +-- src/pipecat/services/xtts/tts.py | 4 +-- 34 files changed, 81 insertions(+), 96 deletions(-) diff --git a/src/pipecat/services/aws/stt.py b/src/pipecat/services/aws/stt.py index b25a5fbb7..58123ac69 100644 --- a/src/pipecat/services/aws/stt.py +++ b/src/pipecat/services/aws/stt.py @@ -181,7 +181,7 @@ class AWSTranscribeSTTService(STTService): try: await self._connect() except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") return # Format the audio data according to AWS event stream format @@ -198,11 +198,11 @@ class AWSTranscribeSTTService(STTService): await self._disconnect() # Don't yield error here - we'll retry on next frame except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") await self._disconnect() except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") await self._disconnect() async def _connect(self): diff --git a/src/pipecat/services/aws/tts.py b/src/pipecat/services/aws/tts.py index e70104614..7e319abea 100644 --- a/src/pipecat/services/aws/tts.py +++ b/src/pipecat/services/aws/tts.py @@ -311,8 +311,9 @@ class AWSPollyTTSService(TTSService): yield frame yield TTSStoppedFrame() - except (BotoCoreError, ClientError) as e: - await self.push_error(exception=e) + except (BotoCoreError, ClientError) as error: + error_message = f"AWS Polly TTS error: {str(error)}" + yield ErrorFrame(error=error_message) finally: yield TTSStoppedFrame() diff --git a/src/pipecat/services/azure/image.py b/src/pipecat/services/azure/image.py index e8148be02..6b0b140e0 100644 --- a/src/pipecat/services/azure/image.py +++ b/src/pipecat/services/azure/image.py @@ -91,7 +91,7 @@ class AzureImageGenServiceREST(ImageGenService): while status != "succeeded": attempts_left -= 1 if attempts_left == 0: - await self.push_error(error_msg="Image generation timed out") + yield ErrorFrame("Image generation timed out") return await asyncio.sleep(1) @@ -103,7 +103,7 @@ class AzureImageGenServiceREST(ImageGenService): image_url = json_response["result"]["data"][0]["url"] if json_response else None if not image_url: - await self.push_error(error_msg="Image generation failed") + yield ErrorFrame("Image generation failed") return # Load the image from the url diff --git a/src/pipecat/services/azure/stt.py b/src/pipecat/services/azure/stt.py index 13c39bcb0..cb3af8fa1 100644 --- a/src/pipecat/services/azure/stt.py +++ b/src/pipecat/services/azure/stt.py @@ -121,7 +121,7 @@ class AzureSTTService(STTService): self._audio_stream.write(audio) yield None except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") async def start(self, frame: StartFrame): """Start the speech recognition service. diff --git a/src/pipecat/services/azure/tts.py b/src/pipecat/services/azure/tts.py index 114768c1a..4ec4d795f 100644 --- a/src/pipecat/services/azure/tts.py +++ b/src/pipecat/services/azure/tts.py @@ -327,7 +327,7 @@ class AzureTTSService(AzureBaseTTSService): try: if self._speech_synthesizer is None: error_msg = "Speech synthesizer not initialized." - await self.push_error(error_msg=error_msg) + yield ErrorFrame(error=error_msg) return try: @@ -354,13 +354,13 @@ class AzureTTSService(AzureBaseTTSService): yield TTSStoppedFrame() except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") yield TTSStoppedFrame() # Could add reconnection logic here if needed return except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") class AzureHttpTTSService(AzureBaseTTSService): @@ -437,4 +437,4 @@ class AzureHttpTTSService(AzureBaseTTSService): cancellation_details = result.cancellation_details logger.warning(f"Speech synthesis canceled: {cancellation_details.reason}") if cancellation_details.reason == CancellationReason.Error: - await self.push_error(error_msg=cancellation_details.error_details) + yield ErrorFrame(error=f"{self} error: {cancellation_details.error_details}") diff --git a/src/pipecat/services/cartesia/tts.py b/src/pipecat/services/cartesia/tts.py index 5dc926a51..70ce91f30 100644 --- a/src/pipecat/services/cartesia/tts.py +++ b/src/pipecat/services/cartesia/tts.py @@ -505,14 +505,14 @@ class CartesiaTTSService(AudioContextWordTTSService): await self._get_websocket().send(msg) await self.start_tts_usage_metrics(text) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") yield TTSStoppedFrame() await self._disconnect() await self._connect() return yield None except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") class CartesiaHttpTTSService(TTSService): diff --git a/src/pipecat/services/deepgram/flux/stt.py b/src/pipecat/services/deepgram/flux/stt.py index ea28ebc7a..0313a5b05 100644 --- a/src/pipecat/services/deepgram/flux/stt.py +++ b/src/pipecat/services/deepgram/flux/stt.py @@ -378,14 +378,14 @@ class DeepgramFluxSTTService(WebsocketSTTService): are issues sending the audio data. """ if not self._websocket: - await self.push_error(error_msg=f"Websocket not connected") + yield ErrorFrame("Not connected to Deepgram Flux.") return try: self._last_stt_time = time.monotonic() await self.send_with_retry(audio, self._report_error) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") return yield None diff --git a/src/pipecat/services/deepgram/tts.py b/src/pipecat/services/deepgram/tts.py index be0d86584..b9ef2d4ac 100644 --- a/src/pipecat/services/deepgram/tts.py +++ b/src/pipecat/services/deepgram/tts.py @@ -116,7 +116,7 @@ class DeepgramTTSService(TTSService): yield TTSStoppedFrame() except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") class DeepgramHttpTTSService(TTSService): @@ -226,4 +226,4 @@ class DeepgramHttpTTSService(TTSService): yield TTSStoppedFrame() except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(f"Error getting audio: {str(e)}") diff --git a/src/pipecat/services/elevenlabs/stt.py b/src/pipecat/services/elevenlabs/stt.py index a901bb82b..763852dca 100644 --- a/src/pipecat/services/elevenlabs/stt.py +++ b/src/pipecat/services/elevenlabs/stt.py @@ -351,7 +351,7 @@ class ElevenLabsSTTService(SegmentedSTTService): ) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") def audio_format_from_sample_rate(sample_rate: int) -> str: @@ -585,7 +585,7 @@ class ElevenLabsRealtimeSTTService(WebsocketSTTService): } await self._websocket.send(json.dumps(message)) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(f"ElevenLabs Realtime STT error: {str(e)}") yield None diff --git a/src/pipecat/services/elevenlabs/tts.py b/src/pipecat/services/elevenlabs/tts.py index 79f59b827..46ffee31c 100644 --- a/src/pipecat/services/elevenlabs/tts.py +++ b/src/pipecat/services/elevenlabs/tts.py @@ -736,13 +736,13 @@ class ElevenLabsTTSService(AudioContextWordTTSService): else: await self._send_text(text) except Exception as e: - await self.push_error(exception=e) yield TTSStoppedFrame() + yield ErrorFrame(error=f"{self} error: {e}") self._started = False return yield None except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") class ElevenLabsHttpTTSService(WordTTSService): @@ -1037,7 +1037,7 @@ class ElevenLabsHttpTTSService(WordTTSService): ) as response: if response.status != 200: error_text = await response.text() - await self.push_error(error_msg=f"ElevenLabs API error: {error_text}") + yield ErrorFrame(error=f"ElevenLabs API error: {error_text}") return await self.start_tts_usage_metrics(text) @@ -1084,7 +1084,7 @@ class ElevenLabsHttpTTSService(WordTTSService): logger.warning(f"Failed to parse JSON from stream: {e}") continue except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") continue # After processing all chunks, emit any remaining partial word @@ -1108,7 +1108,7 @@ class ElevenLabsHttpTTSService(WordTTSService): self._previous_text = text except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") finally: await self.stop_ttfb_metrics() # Let the parent class handle TTSStoppedFrame diff --git a/src/pipecat/services/fal/image.py b/src/pipecat/services/fal/image.py index 3d1999614..6bca6701a 100644 --- a/src/pipecat/services/fal/image.py +++ b/src/pipecat/services/fal/image.py @@ -110,7 +110,7 @@ class FalImageGenService(ImageGenService): image_url = response["images"][0]["url"] if response else None if not image_url: - await self.push_error(error_msg="Image generation failed") + yield ErrorFrame("Image generation failed") return logger.debug(f"Image generated at: {image_url}") diff --git a/src/pipecat/services/fal/stt.py b/src/pipecat/services/fal/stt.py index 966151d42..f70dfcab3 100644 --- a/src/pipecat/services/fal/stt.py +++ b/src/pipecat/services/fal/stt.py @@ -290,4 +290,4 @@ class FalSTTService(SegmentedSTTService): ) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") diff --git a/src/pipecat/services/fish/tts.py b/src/pipecat/services/fish/tts.py index 28f65ef4b..7326439c0 100644 --- a/src/pipecat/services/fish/tts.py +++ b/src/pipecat/services/fish/tts.py @@ -320,7 +320,7 @@ class FishAudioTTSService(InterruptibleTTSService): flush_message = {"event": "flush"} await self._get_websocket().send(ormsgpack.packb(flush_message)) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") yield TTSStoppedFrame() await self._disconnect() await self._connect() @@ -328,4 +328,4 @@ class FishAudioTTSService(InterruptibleTTSService): yield None except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") diff --git a/src/pipecat/services/google/image.py b/src/pipecat/services/google/image.py index 70d92dfc1..f92c7bb2b 100644 --- a/src/pipecat/services/google/image.py +++ b/src/pipecat/services/google/image.py @@ -110,7 +110,7 @@ class GoogleImageGenService(ImageGenService): await self.stop_ttfb_metrics() if not response or not response.generated_images: - await self.push_error(error_msg="Image generation failed") + yield ErrorFrame("Image generation failed") return for img_response in response.generated_images: @@ -127,4 +127,4 @@ class GoogleImageGenService(ImageGenService): yield frame except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(f"Image generation error: {str(e)}") diff --git a/src/pipecat/services/google/tts.py b/src/pipecat/services/google/tts.py index 605306c35..8395c68aa 100644 --- a/src/pipecat/services/google/tts.py +++ b/src/pipecat/services/google/tts.py @@ -737,7 +737,8 @@ class GoogleHttpTTSService(TTSService): yield TTSStoppedFrame() except Exception as e: - await self.push_error(exception=e) + error_message = f"TTS generation error: {str(e)}" + yield ErrorFrame(error=error_message) class GoogleBaseTTSService(TTSService): @@ -1244,4 +1245,5 @@ class GeminiTTSService(GoogleBaseTTSService): yield frame except Exception as e: - await self.push_error(exception=e) + error_message = f"Gemini TTS generation error: {str(e)}" + yield ErrorFrame(error=error_message) diff --git a/src/pipecat/services/groq/tts.py b/src/pipecat/services/groq/tts.py index 64b75560c..aecfdf584 100644 --- a/src/pipecat/services/groq/tts.py +++ b/src/pipecat/services/groq/tts.py @@ -146,6 +146,6 @@ class GroqTTSService(TTSService): bytes = w.readframes(num_frames) yield TTSAudioRawFrame(bytes, frame_rate, channels) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") yield TTSStoppedFrame() diff --git a/src/pipecat/services/heygen/client.py b/src/pipecat/services/heygen/client.py index 16087fb8d..ba517090c 100644 --- a/src/pipecat/services/heygen/client.py +++ b/src/pipecat/services/heygen/client.py @@ -161,7 +161,7 @@ class HeyGenClient: f"{self}::event_callback_task", ) except Exception as e: - await self.push_error(error_msg=f"Failed to setup HeyGenClient: {e}", exception=e) + logger.error(f"Failed to setup HeyGenClient: {e}") await self.cleanup() async def cleanup(self) -> None: @@ -179,7 +179,7 @@ class HeyGenClient: await self._task_manager.cancel_task(self._event_task) self._event_task = None except Exception as e: - await self.push_error(error_msg=f"Exception during cleanup: {e}", exception=e) + logger.error(f"Exception during cleanup: {e}") async def start(self, frame: StartFrame, audio_chunk_size: int) -> None: """Start the client and establish all necessary connections. @@ -229,7 +229,7 @@ class HeyGenClient: self._ws_receive_task_handler(), name="HeyGenClient_Websocket" ) except Exception as e: - await self.push_error(error_msg=f"{self} initialization error: {e}", exception=e) + logger.error(f"{self} initialization error: {e}") self._websocket = None async def _ws_receive_task_handler(self): @@ -242,9 +242,7 @@ class HeyGenClient: except ConnectionClosedOK: break except Exception as e: - await self.push_error( - error_msg=f"Error processing WebSocket message: {e}", exception=e - ) + logger.error(f"Error processing WebSocket message: {e}") break async def _handle_ws_server_event(self, event: dict) -> None: @@ -262,7 +260,7 @@ class HeyGenClient: if self._websocket: await self._websocket.close() except Exception as e: - await self.push_error(error_msg=f"{self} disconnect error: {e}", exception=e) + logger.error(f"{self} disconnect error: {e}") finally: self._websocket = None @@ -275,9 +273,7 @@ class HeyGenClient: if self._websocket: await self._websocket.send(json.dumps(message)) except Exception as e: - await self.push_error( - error_msg=f"Error sending message to HeyGen websocket: {e}", exception=e - ) + logger.error(f"Error sending message to HeyGen websocket: {e}") raise e async def interrupt(self, event_id: str) -> None: @@ -475,11 +471,9 @@ class HeyGenClient: await self._audio_frame_callback(audio_frame) except Exception as e: - await self.push_error( - error_msg=f"Error processing audio frame: {e}", exception=e - ) + logger.error(f"Error processing audio frame: {e}") except Exception as e: - await self.push_error(error_msg=f"Error processing audio frames: {e}", exception=e) + logger.error(f"Error processing audio frames: {e}") finally: logger.debug(f"Audio frame processing ended.") @@ -506,11 +500,9 @@ class HeyGenClient: if self._transport_ready and self._video_frame_callback: await self._video_frame_callback(image_frame) except Exception as e: - await self.push_error( - error_msg=f"Error processing individual video frame: {e}", exception=e - ) + logger.error(f"Error processing individual video frame: {e}") except Exception as e: - await self.push_error(error_msg=f"Error processing video frames: {e}", exception=e) + logger.error(f"Error processing video frames: {e}") finally: logger.debug(f"Video frame processing ended.") @@ -603,7 +595,7 @@ class HeyGenClient: ) except Exception as e: - await self.push_error(error_msg=f"LiveKit initialization error: {e}", exception=e) + logger.error(f"LiveKit initialization error: {e}") self._livekit_room = None async def _livekit_disconnect(self): @@ -624,7 +616,7 @@ class HeyGenClient: self._livekit_room = None logger.debug("Successfully disconnected from LiveKit room") except Exception as e: - await self.push_error(error_msg=f"LiveKit disconnect error: {e}", exception=e) + logger.error(f"LiveKit disconnect error: {e}") # # Queue callback handling diff --git a/src/pipecat/services/lmnt/tts.py b/src/pipecat/services/lmnt/tts.py index be7a1ca76..31bb3aaf3 100644 --- a/src/pipecat/services/lmnt/tts.py +++ b/src/pipecat/services/lmnt/tts.py @@ -299,11 +299,11 @@ class LmntTTSService(InterruptibleTTSService): await self._get_websocket().send(json.dumps({"flush": True})) await self.start_tts_usage_metrics(text) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") yield TTSStoppedFrame() await self._disconnect() await self._connect() return yield None except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") diff --git a/src/pipecat/services/minimax/tts.py b/src/pipecat/services/minimax/tts.py index e0fd0fc3b..992809a83 100644 --- a/src/pipecat/services/minimax/tts.py +++ b/src/pipecat/services/minimax/tts.py @@ -264,7 +264,7 @@ class MiniMaxHttpTTSService(TTSService): ) as response: if response.status != 200: error_message = f"MiniMax TTS error: HTTP {response.status}" - await self.push_error(error_msg=error_message) + yield ErrorFrame(error=error_message) return await self.start_tts_usage_metrics(text) diff --git a/src/pipecat/services/moondream/vision.py b/src/pipecat/services/moondream/vision.py index 795a1057b..e9ce86383 100644 --- a/src/pipecat/services/moondream/vision.py +++ b/src/pipecat/services/moondream/vision.py @@ -110,7 +110,7 @@ class MoondreamService(VisionService): if analysis fails. """ if not self._model: - await self.push_error(error_msg="Moondream model not initialized") + yield ErrorFrame("Moondream model not available") return logger.debug(f"Analyzing image (bytes length: {len(frame.image)})") diff --git a/src/pipecat/services/neuphonic/tts.py b/src/pipecat/services/neuphonic/tts.py index e50762254..28d92ec89 100644 --- a/src/pipecat/services/neuphonic/tts.py +++ b/src/pipecat/services/neuphonic/tts.py @@ -363,14 +363,14 @@ class NeuphonicTTSService(InterruptibleTTSService): await self._send_text(text) await self.start_tts_usage_metrics(text) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") yield TTSStoppedFrame() await self._disconnect() await self._connect() return yield None except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") class NeuphonicHttpTTSService(TTSService): @@ -563,7 +563,7 @@ class NeuphonicHttpTTSService(TTSService): yield TTSAudioRawFrame(audio_bytes, self.sample_rate, 1) except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") # Don't yield error frame for individual message failures continue @@ -571,7 +571,7 @@ class NeuphonicHttpTTSService(TTSService): logger.debug("TTS generation cancelled") raise except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") finally: await self.stop_ttfb_metrics() yield TTSStoppedFrame() diff --git a/src/pipecat/services/openai/image.py b/src/pipecat/services/openai/image.py index 43021b559..9daa8f2b9 100644 --- a/src/pipecat/services/openai/image.py +++ b/src/pipecat/services/openai/image.py @@ -76,7 +76,7 @@ class OpenAIImageGenService(ImageGenService): image_url = image.data[0].url if not image_url: - await self.push_error(error_msg="Image generation failed") + yield ErrorFrame("Image generation failed") return # Load the image from the url diff --git a/src/pipecat/services/openai/tts.py b/src/pipecat/services/openai/tts.py index 422d2ee9e..62f930307 100644 --- a/src/pipecat/services/openai/tts.py +++ b/src/pipecat/services/openai/tts.py @@ -206,4 +206,4 @@ class OpenAITTSService(TTSService): yield frame yield TTSStoppedFrame() except BadRequestError as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") diff --git a/src/pipecat/services/piper/tts.py b/src/pipecat/services/piper/tts.py index 7b7ee5187..f3a76c9e7 100644 --- a/src/pipecat/services/piper/tts.py +++ b/src/pipecat/services/piper/tts.py @@ -88,8 +88,8 @@ class PiperTTSService(TTSService): ) as response: if response.status != 200: error = await response.text() - await self.push_error( - error_msg=f"Error getting audio (status: {response.status}, error: {error})" + yield ErrorFrame( + error=f"Error getting audio (status: {response.status}, error: {error})" ) return diff --git a/src/pipecat/services/playht/tts.py b/src/pipecat/services/playht/tts.py index f8532442d..9e10b413b 100644 --- a/src/pipecat/services/playht/tts.py +++ b/src/pipecat/services/playht/tts.py @@ -391,7 +391,7 @@ class PlayHTTTSService(InterruptibleTTSService): await self._get_websocket().send(json.dumps(tts_command)) await self.start_tts_usage_metrics(text) except Exception as e: - await self.push_error(error_msg=f"Error generating TTS: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") yield TTSStoppedFrame() await self._disconnect() await self._connect() @@ -401,7 +401,7 @@ class PlayHTTTSService(InterruptibleTTSService): yield None except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") class PlayHTHttpTTSService(TTSService): @@ -621,7 +621,7 @@ class PlayHTHttpTTSService(TTSService): yield frame except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") finally: await self.stop_ttfb_metrics() yield TTSStoppedFrame() diff --git a/src/pipecat/services/rime/tts.py b/src/pipecat/services/rime/tts.py index 9bef2b656..c7052efab 100644 --- a/src/pipecat/services/rime/tts.py +++ b/src/pipecat/services/rime/tts.py @@ -408,14 +408,14 @@ class RimeTTSService(AudioContextWordTTSService): await self._get_websocket().send(json.dumps(msg)) await self.start_tts_usage_metrics(text) except Exception as e: - await self.push_error(error_msg=f"Error generating TTS: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") yield TTSStoppedFrame() await self._disconnect() await self._connect() return yield None except Exception as e: - await self.push_error(error_msg=f"Error generating TTS: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") class RimeHttpTTSService(TTSService): @@ -546,7 +546,7 @@ class RimeHttpTTSService(TTSService): ) as response: if response.status != 200: error_message = f"Rime TTS error: HTTP {response.status}" - await self.push_error(error_msg=error_message) + yield ErrorFrame(error=error_message) return await self.start_tts_usage_metrics(text) @@ -563,7 +563,7 @@ class RimeHttpTTSService(TTSService): yield frame except Exception as e: - await self.push_error(error_msg=f"Error generating TTS: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") finally: await self.stop_ttfb_metrics() yield TTSStoppedFrame() diff --git a/src/pipecat/services/riva/stt.py b/src/pipecat/services/riva/stt.py index 871c15f8b..cc4751815 100644 --- a/src/pipecat/services/riva/stt.py +++ b/src/pipecat/services/riva/stt.py @@ -655,12 +655,10 @@ class RivaSegmentedSTTService(SegmentedSTTService): logger.debug("No transcription results found in Riva response") except AttributeError as ae: - await self.push_error( - error_msg=f"Unexpected response structure from Riva: {ae}", exception=ae - ) + yield ErrorFrame(f"Unexpected Riva response format: {str(ae)}") except Exception as e: - await self.push_error(error_msg=f"Error generating STT: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") class ParakeetSTTService(RivaSTTService): diff --git a/src/pipecat/services/riva/tts.py b/src/pipecat/services/riva/tts.py index 0560f4c5f..a18938e5f 100644 --- a/src/pipecat/services/riva/tts.py +++ b/src/pipecat/services/riva/tts.py @@ -180,13 +180,7 @@ class RivaTTSService(TTSService): yield frame resp = await asyncio.wait_for(queue.get(), timeout=RIVA_TTS_TIMEOUT_SECS) except asyncio.TimeoutError: - await self.push_error(error_msg=f"Timeout generating TTS: {text}") - yield TTSStoppedFrame() - return - except Exception as e: - await self.push_error(error_msg=f"Error generating TTS: {e}", exception=e) - yield TTSStoppedFrame() - return + yield ErrorFrame(error=f"{self} error: {e}") await self.start_tts_usage_metrics(text) yield TTSStoppedFrame() diff --git a/src/pipecat/services/sarvam/tts.py b/src/pipecat/services/sarvam/tts.py index 0d21cbb81..3add2c989 100644 --- a/src/pipecat/services/sarvam/tts.py +++ b/src/pipecat/services/sarvam/tts.py @@ -697,11 +697,11 @@ class SarvamTTSService(InterruptibleTTSService): await self._send_text(text) await self.start_tts_usage_metrics(text) except Exception as e: - await self.push_error(error_msg=f"Error sending text: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") yield TTSStoppedFrame() await self._disconnect() await self._connect() return yield None except Exception as e: - await self.push_error(error_msg=f"Error generating TTS: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") diff --git a/src/pipecat/services/speechmatics/stt.py b/src/pipecat/services/speechmatics/stt.py index f85399b09..465200998 100644 --- a/src/pipecat/services/speechmatics/stt.py +++ b/src/pipecat/services/speechmatics/stt.py @@ -467,7 +467,7 @@ class SpeechmaticsSTTService(STTService): await self._client.send_audio(audio) yield None except Exception as e: - await self.push_error(error_msg=f"Error sending audio: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") await self._disconnect() def update_params( diff --git a/src/pipecat/services/ultravox/stt.py b/src/pipecat/services/ultravox/stt.py index 1bcde4b6b..665b288ee 100644 --- a/src/pipecat/services/ultravox/stt.py +++ b/src/pipecat/services/ultravox/stt.py @@ -436,12 +436,12 @@ class UltravoxSTTService(AIService): yield LLMFullResponseEndFrame() except Exception as e: - await self.push_error(error_msg=f"Error generating text: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") else: - await self.push_error(error_msg="No model available for text generation") + yield ErrorFrame("No model available for text generation") except Exception as e: - await self.push_error(error_msg=f"Error processing audio: {e}", exception=e) + yield ErrorFrame(f"Error processing audio: {str(e)}") finally: self._buffer.is_processing = False self._buffer.frames = [] diff --git a/src/pipecat/services/whisper/base_stt.py b/src/pipecat/services/whisper/base_stt.py index fd99502a4..85eb5b63b 100644 --- a/src/pipecat/services/whisper/base_stt.py +++ b/src/pipecat/services/whisper/base_stt.py @@ -226,7 +226,7 @@ class BaseWhisperSTTService(SegmentedSTTService): logger.warning("Received empty transcription from API") except Exception as e: - await self.push_error(exception=e) + yield ErrorFrame(error=f"{self} error: {e}") async def _transcribe(self, audio: bytes) -> Transcription: """Transcribe audio data to text. diff --git a/src/pipecat/services/whisper/stt.py b/src/pipecat/services/whisper/stt.py index 8e7c5d29a..1be1bb20c 100644 --- a/src/pipecat/services/whisper/stt.py +++ b/src/pipecat/services/whisper/stt.py @@ -285,7 +285,7 @@ class WhisperSTTService(SegmentedSTTService): The service will normalize it to float32 in the range [-1, 1]. """ if not self._model: - await self.push_error(error_msg="Whisper model not available") + yield ErrorFrame("Whisper model not available") return await self.start_processing_metrics() @@ -427,4 +427,4 @@ class WhisperSTTServiceMLX(WhisperSTTService): ) except Exception as e: - await self.push_error(error_msg=f"Error processing audio: {e}", exception=e) + yield ErrorFrame(error=f"{self} error: {e}") diff --git a/src/pipecat/services/xtts/tts.py b/src/pipecat/services/xtts/tts.py index 0d4cb9641..56741c416 100644 --- a/src/pipecat/services/xtts/tts.py +++ b/src/pipecat/services/xtts/tts.py @@ -181,9 +181,7 @@ class XTTSService(TTSService): async with self._aiohttp_session.post(url, json=payload) as r: if r.status != 200: text = await r.text() - await self.push_error( - error_msg=f"Error getting audio (status: {r.status}, error: {text})" - ) + yield ErrorFrame(error=f"Error getting audio (status: {r.status}, error: {text})") return await self.start_tts_usage_metrics(text)