Skip to content

Commit 1ccbc5a

Browse files
authored
Expand .text error descriptions. (#527)
* Expand error descriptions for #170 Change-Id: I8599dafc9e5084a43f2ce482644d0e9e16b61061 * Fix test failure cause by upgrade to protobuf>=5.0.0 Change-Id: I16a3c1964284d16efb48073662901454d4e4a6a1 * Format Change-Id: Iee130a7e58f2cfbc1001808ac892f119338626eb
1 parent f03ef2d commit 1ccbc5a

File tree

2 files changed

+60
-9
lines changed

2 files changed

+60
-9
lines changed

google/generativeai/types/generation_types.py

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -412,14 +412,22 @@ def parts(self):
412412
"""
413413
candidates = self.candidates
414414
if not candidates:
415-
raise ValueError(
415+
msg = (
416416
"Invalid operation: The `response.parts` quick accessor requires a single candidate, "
417-
"but none were returned. Please check the `response.prompt_feedback` to determine if the prompt was blocked."
417+
"but but `response.candidates` is empty."
418418
)
419+
if self.prompt_feedback:
420+
raise ValueError(
421+
msg + "\nThis appears to be caused by a blocked prompt, "
422+
f"see `response.prompt_feedback`: {self.prompt_feedback}"
423+
)
424+
else:
425+
raise ValueError(msg)
426+
419427
if len(candidates) > 1:
420428
raise ValueError(
421-
"Invalid operation: The `response.parts` quick accessor requires a single candidate. "
422-
"For multiple candidates, please use `result.candidates[index].text`."
429+
"Invalid operation: The `response.parts` quick accessor retrieves the parts for a single candidate. "
430+
"This response contains multiple candidates, please use `result.candidates[index].text`."
423431
)
424432
parts = candidates[0].content.parts
425433
return parts
@@ -433,10 +441,53 @@ def text(self):
433441
"""
434442
parts = self.parts
435443
if not parts:
436-
raise ValueError(
437-
"Invalid operation: The `response.text` quick accessor requires the response to contain a valid `Part`, "
438-
"but none were returned. Please check the `candidate.safety_ratings` to determine if the response was blocked."
444+
candidate = self.candidates[0]
445+
446+
fr = candidate.finish_reason
447+
FinishReason = protos.Candidate.FinishReason
448+
449+
msg = (
450+
"Invalid operation: The `response.text` quick accessor requires the response to contain a valid "
451+
"`Part`, but none were returned. The candidate's "
452+
f"[finish_reason](https://ai.google.dev/api/generate-content#finishreason) is {fr}."
439453
)
454+
if candidate.finish_message:
455+
msg += 'The `finish_message` is "{candidate.finish_message}".'
456+
457+
if fr is FinishReason.FINISH_REASON_UNSPECIFIED:
458+
raise ValueError(msg)
459+
elif fr is FinishReason.STOP:
460+
raise ValueError(msg)
461+
elif fr is FinishReason.MAX_TOKENS:
462+
raise ValueError(msg)
463+
elif fr is FinishReason.SAFETY:
464+
raise ValueError(
465+
msg + f" The candidate's safety_ratings are: {candidate.safety_ratings}.",
466+
candidate.safety_ratings,
467+
)
468+
elif fr is FinishReason.RECITATION:
469+
raise ValueError(
470+
msg + " Meaning that the model was reciting from copyrighted material."
471+
)
472+
elif fr is FinishReason.LANGUAGE:
473+
raise ValueError(msg + " Meaning the response was using an unsupported language.")
474+
elif fr is FinishReason.OTHER:
475+
raise ValueError(msg)
476+
elif fr is FinishReason.BLOCKLIST:
477+
raise ValueError(msg)
478+
elif fr is FinishReason.PROHIBITED_CONTENT:
479+
raise ValueError(msg)
480+
elif fr is FinishReason.SPII:
481+
raise ValueError(msg + " SPII - Sensitive Personally Identifiable Information.")
482+
elif fr is FinishReason.MALFORMED_FUNCTION_CALL:
483+
raise ValueError(
484+
msg + " Meaning that model generated a `FunctionCall` that was invalid. "
485+
"Setting the "
486+
"[Function calling mode](https://ai.google.dev/gemini-api/docs/function-calling#function_calling_mode) "
487+
"to `ANY` can fix this because it enables constrained decoding."
488+
)
489+
else:
490+
raise ValueError(msg)
440491

441492
texts = []
442493
for part in parts:

tests/test_generative_models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,13 +1120,13 @@ def test_repr_error_info_for_chat_streaming_unexpected_stop(self):
11201120
"usage_metadata": {}
11211121
}),
11221122
),
1123-
error=<StopCandidateException> index: 0
1124-
content {
1123+
error=<StopCandidateException> content {
11251124
parts {
11261125
text: "abc"
11271126
}
11281127
}
11291128
finish_reason: SAFETY
1129+
index: 0
11301130
citation_metadata {
11311131
}
11321132
"""

0 commit comments

Comments
 (0)