Error Handling Guide
Core Error Indicators
Key criteria for detecting errors in Gemini API responses
Priority Detection Order
1️⃣ candidatesTokenCount = 0 (Highest Priority)
Most Reliable Indicator: Content review rejection
if (data.usageMetadata?.candidatesTokenCount === 0) {
// Content rejected at review stage
return { error: 'CONTENT_REVIEW_REJECTED' };
}Characteristics:
- Rejected before generation starts
finishReasonmay still be "STOP" (misleading!)partsarray is empty
2️⃣ finishReason != STOP (High Priority)
Values:
PROHIBITED_CONTENT- Violates policySAFETY- Triggers safety filterRECITATION- Copyright concernsMAX_TOKENS- Length exceeded
const finishReason = data.candidates[0].finishReason;
if (finishReason && finishReason !== 'STOP') {
return { error: 'GENERATION_REJECTED', reason: finishReason };
}3️⃣ Text Response (Medium Priority)
No image data, only text explanation
const parts = data.candidates[0].content.parts;
const hasImage = parts.some(p => p.inlineData?.data);
const hasText = parts.some(p => p.text);
if (!hasImage && hasText) {
return { error: 'TEXT_RESPONSE', text: parts[0].text };
}4️⃣ Knowledge Cutoff (Low Priority)
Model mentions knowledge limitations
if (text.includes("knowledge cutoff") ||
text.includes("after April 2023")) {
return { error: 'KNOWLEDGE_CUTOFF' };
}Detection Flow
function detectError(data) {
// 1. Content review
if (data.usageMetadata?.candidatesTokenCount === 0) {
return 'CONTENT_REVIEW_REJECTED';
}
// 2. Generation rejection
const finishReason = data.candidates?.[0]?.finishReason;
if (finishReason && finishReason !== 'STOP') {
return `FINISH_REASON_${finishReason}`;
}
// 3. Check parts
const parts = data.candidates?.[0]?.content?.parts || [];
const hasImage = parts.some(p => p.inlineData?.data);
if (hasImage) {
return 'SUCCESS';
}
// 4. Text response
if (parts.some(p => p.text)) {
return 'TEXT_RESPONSE';
}
return 'UNKNOWN_ERROR';
}Common Pitfalls
❌ Don't check finishReason === "STOP" first
✅ Do check candidatesTokenCount first
❌ Don't assume empty parts means error
✅ Do check candidatesTokenCount to distinguish
❌ Don't ignore text responses
✅ Do parse and display rejection reasons
Related Docs
How is this guide?