Add comprehensive error handling to OpenAI LLM service
- Import ErrorFrame from pipecat.frames.frames - Add catch-all exception handler matching Anthropic service pattern - Handle asyncio.CancelledError by re-raising to maintain proper cancellation - Catch and log all other exceptions with full traceback - Push ErrorFrame upstream on exceptions for error detection - Maintain existing httpx.TimeoutException handling - Ensure LLMFullResponseEndFrame always sent in finally block This change enables consistent error propagation across all LLM services, allowing downstream error monitors to detect failures and implement fallback strategies like LLM hot-switching. Fixes issue where OpenAI service errors were suppressed and not communicated through the frame pipeline, making automatic error recovery impossible.
This commit is contained in:
@@ -13,18 +13,13 @@ from typing import Any, Dict, List, Mapping, Optional
|
||||
|
||||
import httpx
|
||||
from loguru import logger
|
||||
from openai import (
|
||||
NOT_GIVEN,
|
||||
APITimeoutError,
|
||||
AsyncOpenAI,
|
||||
AsyncStream,
|
||||
DefaultAsyncHttpxClient,
|
||||
)
|
||||
from openai import NOT_GIVEN, APITimeoutError, AsyncOpenAI, AsyncStream, DefaultAsyncHttpxClient
|
||||
from openai.types.chat import ChatCompletionChunk, ChatCompletionMessageParam
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from pipecat.adapters.services.open_ai_adapter import OpenAILLMInvocationParams
|
||||
from pipecat.frames.frames import (
|
||||
ErrorFrame,
|
||||
Frame,
|
||||
LLMContextFrame,
|
||||
LLMFullResponseEndFrame,
|
||||
@@ -460,8 +455,13 @@ class BaseOpenAILLMService(LLMService):
|
||||
await self.push_frame(LLMFullResponseStartFrame())
|
||||
await self.start_processing_metrics()
|
||||
await self._process_context(context)
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
except httpx.TimeoutException:
|
||||
await self._call_event_handler("on_completion_timeout")
|
||||
except Exception as e:
|
||||
logger.exception(f"{self} exception: {e}")
|
||||
await self.push_error(ErrorFrame(f"{e}"))
|
||||
finally:
|
||||
await self.stop_processing_metrics()
|
||||
await self.push_frame(LLMFullResponseEndFrame())
|
||||
|
||||
Reference in New Issue
Block a user