Handle None on the response candidates in Google Generative AI (#142497)

* Added type checking on the candidates list

* Made error message a constant
This commit is contained in:
Ivan Lopez Hernandez 2025-04-07 21:20:54 -07:00 committed by Franck Nijhof
parent f702f3efcd
commit c540acf2bd
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
2 changed files with 39 additions and 4 deletions

View File

@ -55,6 +55,10 @@ from .const import (
# Max number of back and forth with the LLM to generate a response
MAX_TOOL_ITERATIONS = 10
ERROR_GETTING_RESPONSE = (
"Sorry, I had a problem getting a response from Google Generative AI."
)
async def async_setup_entry(
hass: HomeAssistant,
@ -429,6 +433,12 @@ class GoogleGenerativeAIConversationEntity(
raise HomeAssistantError(
f"The message got blocked due to content violations, reason: {chat_response.prompt_feedback.block_reason_message}"
)
if not chat_response.candidates:
LOGGER.error(
"No candidates found in the response: %s",
chat_response,
)
raise HomeAssistantError(ERROR_GETTING_RESPONSE)
except (
APIError,
@ -452,9 +462,7 @@ class GoogleGenerativeAIConversationEntity(
response_parts = chat_response.candidates[0].content.parts
if not response_parts:
raise HomeAssistantError(
"Sorry, I had a problem getting a response from Google Generative AI."
)
raise HomeAssistantError(ERROR_GETTING_RESPONSE)
content = " ".join(
[part.text.strip() for part in response_parts if part.text]
)

View File

@ -12,6 +12,7 @@ import voluptuous as vol
from homeassistant.components import conversation
from homeassistant.components.conversation import UserContent, async_get_chat_log, trace
from homeassistant.components.google_generative_ai_conversation.conversation import (
ERROR_GETTING_RESPONSE,
_escape_decode,
_format_schema,
)
@ -492,7 +493,33 @@ async def test_empty_response(
assert result.response.response_type == intent.IntentResponseType.ERROR, result
assert result.response.error_code == "unknown", result
assert result.response.as_dict()["speech"]["plain"]["speech"] == (
"Sorry, I had a problem getting a response from Google Generative AI."
ERROR_GETTING_RESPONSE
)
@pytest.mark.usefixtures("mock_init_component")
async def test_none_response(
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test empty response."""
with patch("google.genai.chats.AsyncChats.create") as mock_create:
mock_chat = AsyncMock()
mock_create.return_value.send_message = mock_chat
chat_response = Mock(prompt_feedback=None)
mock_chat.return_value = chat_response
chat_response.candidates = None
result = await conversation.async_converse(
hass,
"hello",
None,
Context(),
agent_id="conversation.google_generative_ai_conversation",
)
assert result.response.response_type == intent.IntentResponseType.ERROR, result
assert result.response.error_code == "unknown", result
assert result.response.as_dict()["speech"]["plain"]["speech"] == (
ERROR_GETTING_RESPONSE
)