MemberJunction / MemberJunction/MJ
Gemini provider should classify fetch/network errors as transient for proper retry
- Dominant language
- TSQL
- Stars
- 29
- Forks
- 6
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 308
Description
## Problem
When the Google GenAI SDK throws `TypeError: fetch failed sending request` (a network-level failure), the Gemini LLM driver passes it through unclassified. The `AIPromptRunner` error classifier maps it to `errorType: 'Unknown'` which limits retries to 2 attempts instead of treating it as a transient error with exponential backoff.
This causes the autotagging pipeline to skip records unnecessarily when Google's API has intermittent connectivity issues (connection resets, DNS timeouts, TLS errors).
## Current Behavior
```
errorType: 'Unknown'
willRetry: false (on attempt 2)
error: 'exception TypeError: fetch failed sending request'
```
After 2 failover attempts (Vertex AI vendor → Google vendor), the runner gives up and continues with "Warn mode — continuing with invalid output."
## Expected Behavior
The Gemini driver should catch `TypeError` from the `@google/genai` SDK's `fetch()` calls and reclassify them as transient network errors so the retry system can:
- Apply exponential backoff (30s, 60s, 120s)
- Retry more than 2 times for network errors
- Distinguish between "API rejected my request" (non-retryable) and "network failed" (retryable)
## Suggested Fix
In the Gemini provider's error handling (likely in `GeminiLLM.nonStreamingChatCompletion` or its caller), catch `TypeError` specifically and wrap it in an error type that the `AIPromptRunner` classifies as `'Transient'`:
```typescript
} catch (error) {
if (error instanceof TypeError && error.message.includes('fetch failed')) {
// Network-level failure — retryable
throw new TransientError(`Network error calling Gemini API: ${error.message}`, error);
}
throw error;
}
```
## Impact
During a 7,075-item autotagging pipeline run with Gemini 3.1 Flash-Lite, approximately 200-300 items fail due to these transient errors on each run. The retry mechanism we built (`GetUntaggedContentItems`) catches them on subsequent runs, but proper transient error classification would reduce the number of failed items per run significantly.
## Files
- `packages/AI/Providers/Gemini/src/` — Gemini LLM driver
- `packages/AI/Prompts/src/AIPromptRunner.ts` — error classification and retry logic
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Contributor guide
Research direction
Start in packages/AI/Providers/Gemini/src/ and trace GeminiLLM.nonStreamingChatCompletion or its caller, then read the classification and retry flow in packages/AI/Prompts/src/AIPromptRunner.ts. Verify how the SDK's fetch failure is represented and how transient errors are handled. Done means network-level TypeError failures are retryable while API-rejected requests retain their existing classification.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100