diff --git a/CHANGELOG.md b/CHANGELOG.md index 41e8b9639..0bca536c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Added logging and improved error handling to help diagnose and prevent potential +- Added logging and improved error handling to help diagnose and prevent potential Pipeline freezes. - Introduce task watchdog timers. Watchdog timers are used to detect if a @@ -52,7 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `LLMAssistantContextAggregator` that exposes whether a function call is in progress. -- Added `SambaNovaLLMService` which provides llm api integration with an +- Added `SambaNovaLLMService` which provides llm api integration with an OpenAI-compatible interface. - Added `SambaNovaTTSService` which provides speech-to-text functionality using @@ -84,15 +84,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Fixed an issue in `FastAPIWebsocketClient` to ensure proper disconnection +- Fixed an issue in `FastAPIWebsocketClient` to ensure proper disconnection when the websocket is already closed. - Fixed an issue where the `UserStoppedSpeakingFrame` was not received if the transport was not receiving new audio frames. -- Fixed an edge case where if the user interrupted the bot but no new aggregation +- Fixed an edge case where if the user interrupted the bot but no new aggregation was received, the bot would not resume speaking. +- Fixed an issue with `TelnyxFrameSerializer` where it would throw an exception + when the user hung up the call. + - Fixed an issue with `ElevenLabsTTSService` where the context was not being closed. diff --git a/src/pipecat/serializers/telnyx.py b/src/pipecat/serializers/telnyx.py index 6ef9f7c0d..5f8a09252 100644 --- a/src/pipecat/serializers/telnyx.py +++ b/src/pipecat/serializers/telnyx.py @@ -196,8 +196,31 @@ class TelnyxFrameSerializer(FrameSerializer): async with session.post(endpoint, headers=headers) as response: if response.status == 200: logger.info(f"Successfully terminated Telnyx call {call_control_id}") + elif response.status == 422: + # Handle the case where the call has already ended + # Error code 90018: "Call has already ended" + # Source: https://developers.telnyx.com/api/errors/90018 + try: + error_data = await response.json() + if any( + error.get("code") == "90018" + for error in error_data.get("errors", []) + ): + logger.debug( + f"Telnyx call {call_control_id} was already terminated" + ) + return + except: + pass # Fall through to log the raw error + + # Log other 422 errors + error_text = await response.text() + logger.error( + f"Failed to terminate Telnyx call {call_control_id}: " + f"Status {response.status}, Response: {error_text}" + ) else: - # Get the error details for better debugging + # Log other errors error_text = await response.text() logger.error( f"Failed to terminate Telnyx call {call_control_id}: "