add catch-all exception handler per review feedback

This commit is contained in:
Luke Payyapilli
2026-01-29 09:07:06 -05:00
parent ff0eb6d286
commit 433c1b9b92
2 changed files with 39 additions and 1 deletions

View File

@@ -495,6 +495,8 @@ class BaseOpenAILLMService(LLMService):
except httpx.TimeoutException as e:
await self._call_event_handler("on_completion_timeout")
await self.push_error(error_msg="LLM completion timeout", exception=e)
except Exception as e:
await self.push_error(error_msg=f"Error during completion: {e}", exception=e)
finally:
await self.stop_processing_metrics()
await self.push_frame(LLMFullResponseEndFrame())

View File

@@ -4,7 +4,7 @@
# SPDX-License-Identifier: BSD 2-Clause License
#
"""Unit tests for OpenAI LLM timeout handling."""
"""Unit tests for OpenAI LLM error handling."""
from unittest.mock import AsyncMock, patch
@@ -125,3 +125,39 @@ async def test_openai_llm_timeout_still_pushes_end_frame():
# Verify metrics were stopped
service.stop_processing_metrics.assert_called_once()
@pytest.mark.asyncio
async def test_openai_llm_emits_error_frame_on_exception():
"""Test that OpenAI LLM service emits ErrorFrame when a general exception occurs.
This enables proper error handling for API errors, rate limits, and other failures.
"""
with patch.object(OpenAILLMService, "create_client"):
service = OpenAILLMService(model="gpt-4")
service._client = AsyncMock()
pushed_errors = []
async def mock_push_error(error_msg, exception=None):
pushed_errors.append({"error_msg": error_msg, "exception": exception})
service.push_frame = AsyncMock()
service.push_error = mock_push_error
service._call_event_handler = AsyncMock()
service._process_context = AsyncMock(side_effect=RuntimeError("API Error"))
service.start_processing_metrics = AsyncMock()
service.stop_processing_metrics = AsyncMock()
context = LLMContext(
messages=[{"role": "user", "content": "Hello"}],
)
frame = LLMContextFrame(context=context)
await service.process_frame(frame, FrameDirection.DOWNSTREAM)
# Verify push_error was called with correct message
assert len(pushed_errors) == 1
assert "Error during completion" in pushed_errors[0]["error_msg"]
assert "API Error" in pushed_errors[0]["error_msg"]
assert isinstance(pushed_errors[0]["exception"], RuntimeError)