209 lines
7.5 KiB
Markdown
209 lines
7.5 KiB
Markdown
# LinkedIn Writer Timeout and Connection Issues - Complete Fix
|
|
|
|
## 🐛 **Issues Identified from Logs**
|
|
|
|
### **Primary Issue: Gemini API Connection Timeout**
|
|
```
|
|
ERROR|gemini_grounded_provider.py:99:generate_grounded_content| ❌ Error generating grounded content: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
|
|
```
|
|
|
|
### **Secondary Issues:**
|
|
1. **Frontend timeout**: 60-second frontend timeout being hit
|
|
2. **No fallback mechanism**: When Gemini fails, entire generation fails
|
|
3. **Research sources**: 0 sources found because grounding failed
|
|
4. **Loading state issues**: Fixed in previous session
|
|
|
|
## ✅ **Comprehensive Fixes Implemented**
|
|
|
|
### **1. Backend Fallback Mechanism**
|
|
|
|
**File**: `backend/services/linkedin/content_generator.py`
|
|
|
|
Added robust fallback logic when Gemini grounded provider fails:
|
|
|
|
```python
|
|
except Exception as e:
|
|
logger.error(f"Error generating grounded post content: {str(e)}")
|
|
logger.info("Attempting fallback to standard content generation...")
|
|
|
|
# Fallback to standard content generation without grounding
|
|
try:
|
|
if not self.fallback_provider:
|
|
raise Exception("No fallback provider available")
|
|
|
|
# Build a simpler prompt for fallback generation
|
|
prompt = PostPromptBuilder.build_post_prompt(request)
|
|
|
|
# Generate content using fallback provider
|
|
result = await self.fallback_provider.generate_content(
|
|
prompt=prompt,
|
|
temperature=0.7,
|
|
max_tokens=request.max_length
|
|
)
|
|
|
|
# Return result in the expected format
|
|
return {
|
|
'content': result.get('content', ''),
|
|
'sources': [],
|
|
'citations': [],
|
|
'grounding_enabled': False,
|
|
'fallback_used': True
|
|
}
|
|
|
|
except Exception as fallback_error:
|
|
logger.error(f"Fallback generation also failed: {str(fallback_error)}")
|
|
raise Exception(f"Failed to generate content: {str(e)}. Fallback also failed: {str(fallback_error)}")
|
|
```
|
|
|
|
### **2. Gemini Provider Timeout Configuration**
|
|
|
|
**File**: `backend/services/llm_providers/gemini_grounded_provider.py`
|
|
|
|
Added timeout handling to prevent indefinite hanging:
|
|
|
|
```python
|
|
# Initialize the Gemini client with timeout configuration
|
|
self.client = genai.Client(api_key=self.api_key)
|
|
self.timeout = 30 # 30 second timeout for API calls
|
|
|
|
# Make the request with native grounding and timeout
|
|
import asyncio
|
|
try:
|
|
response = await asyncio.wait_for(
|
|
self.client.models.generate_content(
|
|
model="gemini-2.5-flash",
|
|
contents=grounded_prompt,
|
|
config=config,
|
|
),
|
|
timeout=self.timeout
|
|
)
|
|
except asyncio.TimeoutError:
|
|
raise Exception(f"Gemini API request timed out after {self.timeout} seconds")
|
|
```
|
|
|
|
### **3. Frontend Timeout Extension**
|
|
|
|
**File**: `frontend/src/services/linkedInWriterApi.ts`
|
|
|
|
Updated LinkedIn writer API calls to use `aiApiClient` with 3-minute timeout instead of 60-second timeout:
|
|
|
|
```typescript
|
|
// Changed from apiClient (60s timeout) to aiApiClient (180s timeout)
|
|
async generatePost(request: LinkedInPostRequest): Promise<LinkedInPostResponse> {
|
|
const { data } = await aiApiClient.post('/api/linkedin/generate-post', request);
|
|
return data;
|
|
},
|
|
|
|
async generateArticle(request: LinkedInArticleRequest): Promise<LinkedInArticleResponse> {
|
|
const { data } = await aiApiClient.post('/api/linkedin/generate-article', request);
|
|
return data;
|
|
},
|
|
|
|
async generateCarousel(request: LinkedInCarouselRequest): Promise<LinkedInCarouselResponse> {
|
|
const { data } = await aiApiClient.post('/api/linkedin/generate-carousel', request);
|
|
return data;
|
|
},
|
|
|
|
async generateVideoScript(request: LinkedInVideoScriptRequest): Promise<LinkedInVideoScriptResponse> {
|
|
const { data } = await aiApiClient.post('/api/linkedin/generate-video-script', request);
|
|
return data;
|
|
},
|
|
```
|
|
|
|
### **4. Loading State Management (Previously Fixed)**
|
|
|
|
**File**: `frontend/src/components/LinkedInWriter/RegisterLinkedInActions.tsx`
|
|
|
|
Added proper loading start/end events:
|
|
|
|
```typescript
|
|
// Start loading state
|
|
window.dispatchEvent(new CustomEvent('linkedinwriter:loadingStart', {
|
|
detail: {
|
|
action: 'generateLinkedInPost',
|
|
message: 'Generating LinkedIn post with persona optimization...'
|
|
}
|
|
}));
|
|
|
|
// End loading state
|
|
window.dispatchEvent(new CustomEvent('linkedinwriter:loadingEnd'));
|
|
```
|
|
|
|
## 🔧 **How the Fixes Work Together**
|
|
|
|
### **Error Handling Flow**
|
|
|
|
1. **Gemini API Call**: Attempts to use Gemini with 30-second timeout
|
|
2. **Timeout/Connection Error**: If Gemini fails, fallback is triggered
|
|
3. **Fallback Generation**: Uses alternative LLM provider (OpenAI/Anthropic)
|
|
4. **Content Generation**: Produces content without grounding but still functional
|
|
5. **Frontend Handling**: 3-minute timeout allows for retry/fallback scenarios
|
|
6. **Loading States**: Proper feedback throughout the process
|
|
|
|
### **Timeout Configuration**
|
|
|
|
- **Gemini API**: 30 seconds (prevents indefinite hanging)
|
|
- **Frontend API**: 180 seconds (3 minutes for AI operations)
|
|
- **Backend Processing**: Graceful fallback within 30 seconds
|
|
|
|
## 🧪 **Testing the Fixes**
|
|
|
|
### **Expected Behavior**
|
|
|
|
1. **Normal Operation**: Gemini works → Grounded content with sources
|
|
2. **Gemini Failure**: Fallback triggered → Content generated without grounding
|
|
3. **Network Issues**: Timeout after 30 seconds → Fallback to alternative provider
|
|
4. **Frontend**: No more 60-second timeouts, proper loading states
|
|
|
|
### **Debug Information**
|
|
|
|
Check logs for these messages:
|
|
- `"Attempting fallback to standard content generation..."`
|
|
- `"Gemini API request timed out after 30 seconds"`
|
|
- `"Fallback generation also failed"` (if both fail)
|
|
|
|
## 🚀 **Benefits of the Fixes**
|
|
|
|
### **1. Reliability**
|
|
- **Graceful degradation**: System continues working even when Gemini fails
|
|
- **Multiple fallbacks**: Primary → Secondary → Error handling
|
|
- **Timeout protection**: No more indefinite hanging
|
|
|
|
### **2. User Experience**
|
|
- **Faster feedback**: 30-second timeout instead of indefinite waiting
|
|
- **Proper loading states**: Users see progress throughout
|
|
- **Content generation**: Always produces content, even without grounding
|
|
|
|
### **3. System Stability**
|
|
- **Network resilience**: Handles connection issues gracefully
|
|
- **API reliability**: Multiple provider options
|
|
- **Error recovery**: Automatic fallback mechanisms
|
|
|
|
## 📋 **Verification Checklist**
|
|
|
|
- [ ] Gemini API timeout after 30 seconds (not indefinite)
|
|
- [ ] Fallback content generation when Gemini fails
|
|
- [ ] Frontend timeout extended to 3 minutes
|
|
- [ ] Loading states work properly throughout
|
|
- [ ] Content generated even without grounding
|
|
- [ ] Error messages are informative
|
|
- [ ] System recovers from network issues
|
|
|
|
## 🔮 **Future Improvements**
|
|
|
|
1. **Health Checks**: Monitor Gemini API availability
|
|
2. **Circuit Breaker**: Temporarily disable Gemini if consistently failing
|
|
3. **Retry Logic**: Automatic retry with exponential backoff
|
|
4. **Metrics**: Track fallback usage and success rates
|
|
5. **User Notification**: Inform users when fallback is used
|
|
|
|
## 🎯 **Root Cause Resolution**
|
|
|
|
The timeout issues were caused by:
|
|
1. **No timeout on Gemini API calls** → Fixed with 30-second timeout
|
|
2. **No fallback mechanism** → Fixed with automatic fallback
|
|
3. **Frontend timeout too short** → Fixed with 3-minute timeout
|
|
4. **Poor error handling** → Fixed with comprehensive error management
|
|
|
|
The system now handles network issues gracefully and provides a reliable content generation experience even when external APIs fail.
|