Ziya/architecture/IPFS_RETRY_IMPLEMENTATION.md
rizary 67fb3a203e
feat: implement CEX analysis cards and real-time token monitoring
- Add TokenCard and CexAnalysisCard components for displaying token data
- Implement real-time Redis event streaming for token updates
- Add environment-based configuration system for dev/prod Redis servers
- Create comprehensive hunting ground dashboard with card management
- Add individual and bulk card removal functionality
- Implement browser integration for token details viewing
- Add timestamp utilities and proper type handling for Redis events
- Create production-ready configuration with 154.38.185.112 Redis server
- Add comprehensive documentation in README.md and CONTRIBUTORS.md
- Restructure project architecture with proper Electron-Vue integration

BREAKING CHANGE: Redis configuration now uses environment-based settings
2025-06-23 09:03:39 +07:00

283 lines
No EOL
8.8 KiB
Markdown

# IPFS Retry Implementation & Error Handling
## Overview
This document outlines the comprehensive retry mechanism and error handling improvements implemented for IPFS metadata fetching to resolve `AbortError: signal is aborted without reason` issues and CORS-related problems.
## Key Features Implemented
### 1. Enhanced IPFS Utility (`app/utils/ipfs.ts`)
#### Retry Configuration
- **Max Retries**: 5 attempts per gateway (automatic fallback)
- **Timeout**: 8 seconds per individual request
- **Gateway Rotation**: Automatic fallback to next gateway on failure
#### CORS-Friendly Gateway Strategy
```typescript
const IPFS_GATEWAYS = [
'https://dweb.link/ipfs/',
'https://nftstorage.link/ipfs/',
'https://cloudflare-ipfs.com/ipfs/',
'https://gateway.pinata.cloud/ipfs/',
'https://ipfs.io/ipfs/'
];
```
**Gateway Selection Strategy:**
- Prioritizes CORS-friendly gateways (`dweb.link`, `nftstorage.link`)
- Falls back to other reliable gateways
- Automatic rotation on failure
#### Smart Error Handling
- **Content-Type Validation**: Ensures response is JSON before parsing
- **Network Error Detection**: Distinguishes between network and parsing errors
- **Graceful Degradation**: Returns `null` on failure instead of throwing errors
- **Gateway Isolation**: Individual gateway failures don't affect others
#### Caching Mechanism
- **Simple Map-based Cache**: Prevents duplicate requests for same URIs
- **Memory Management**: Configurable cache with statistics
- **Cache Utilities**: `clearMetadataCache()` and `getCacheStats()` functions
### 2. Enhanced TokenCard Component (`app/components/TokenCard.vue`)
#### Direct Metadata Integration
- **Non-blocking Loading**: Metadata loads after component mounts
- **Individual Error Handling**: Card failures don't affect others
- **Visual Feedback**: Loading spinners and error indicators
#### Social Media Integration
```typescript
// Automatic detection of social links
const socialLinks = extractSocialLinks(metadata);
// Returns: { type: 'twitter', url: string, icon: string }[]
```
**Supported Platforms:**
- Twitter/X (twitter.com, x.com)
- Telegram (t.me, telegram.org)
- Discord (discord.gg, discord.com)
- Generic Website (fallback)
#### Image Handling
- **IPFS Image Support**: Automatic IPFS hash extraction and gateway routing
- **Fallback Avatars**: Gradient avatars with token symbol when images fail
- **Error Recovery**: Graceful handling of image load failures
## Core Functions
### Primary Functions
#### `fetchTokenMetadata(uri: string): Promise<TokenMetadata | null>`
- Fetches metadata from IPFS URI
- Handles multiple URI formats (ipfs://, https://ipfs.io/ipfs/, direct hash)
- Returns `null` on failure (no exceptions thrown)
- Automatic caching to prevent duplicate requests
#### `getTokenImage(metadata: TokenMetadata): string | null`
- Extracts and formats token image URL
- Handles IPFS URIs and direct URLs
- Uses reliable gateways for IPFS images
#### `extractSocialLinks(metadata: TokenMetadata)`
- Extracts social media links from metadata
- Returns array of social link objects with icons
- Validates and cleans URLs
### Utility Functions
#### `extractIpfsHash(uri: string): string | null`
- Extracts IPFS hash from various URI formats
- Supports ipfs://, gateway URLs, and direct hashes
#### `getSocialIcon(url: string): string | null`
- Determines appropriate icon for social media URL
- Returns icon identifier for UI rendering
#### `cleanSocialUrl(url: string): string | null`
- Validates and normalizes social media URLs
- Adds https:// prefix when missing
## CORS Resolution
### Problem Identified
Initial implementation encountered CORS errors:
```
Access to fetch at 'https://ipfs.io/ipfs/...' from origin 'http://localhost:3000'
has been blocked by CORS policy: Request header field cache-control is not
allowed by Access-Control-Allow-Headers in preflight response.
```
### Solutions Attempted
#### 1. Server API Route Approach (Abandoned)
- Created Nuxt server API route to proxy IPFS requests
- Issues: Returned HTML instead of JSON in Electron environment
- Not compatible with Electron + Nuxt setup
#### 2. CORS-Friendly Gateway Strategy (Final Solution)
- Prioritized gateways with proper CORS headers
- `dweb.link` and `nftstorage.link` as primary gateways
- Removed problematic headers from requests
- Simplified request configuration
### Final Working Configuration
```typescript
const response = await fetch(url, {
method: 'GET',
mode: 'cors',
headers: {
'Accept': 'application/json',
},
signal: AbortSignal.timeout(8000)
});
```
## Architecture Decisions
### Why Direct Implementation Over Composables
1. **Simplicity**: Direct metadata fetching in components is easier to debug
2. **Performance**: Eliminates unnecessary abstraction layers
3. **Maintenance**: Fewer files to maintain and update
4. **Debugging**: Clearer error tracking and logging
### Why Multiple Gateways
1. **Reliability**: Fallback ensures higher success rate
2. **Performance**: Different gateways have varying response times
3. **CORS Compatibility**: Not all gateways support CORS properly
4. **Geographic Distribution**: Better global accessibility
### Why Simple Caching
1. **Memory Efficiency**: Map-based cache with minimal overhead
2. **Request Deduplication**: Prevents multiple requests for same URI
3. **No Persistence**: Cache clears on app restart (prevents stale data)
4. **Statistics**: Built-in cache monitoring
## Error Handling Strategy
### Non-Blocking Operations
- Individual token failures don't affect others
- UI remains responsive during metadata fetching
- Graceful degradation with fallback content
### User Experience
- **Loading States**: Clear visual feedback during fetching
- **Error Indicators**: Subtle error icons with tooltips
- **Fallback Content**: Token symbol avatars when images fail
- **Retry Capability**: Users can refresh individual tokens
### Developer Experience
- **No Console Spam**: Removed all debugging output
- **Clear Error Types**: Distinguishable error conditions
- **Cache Management**: Tools for cache inspection and clearing
## Performance Optimizations
### Request Optimization
- 8-second timeout prevents hanging requests
- Automatic gateway rotation minimizes wait time
- Content-type validation prevents unnecessary parsing
- Simple caching reduces duplicate requests
### UI Optimization
- Non-blocking metadata loading
- Individual component error isolation
- Efficient social link extraction
- Optimized image loading with fallbacks
## Implementation Status
### ✅ Completed Features
- [x] Multiple CORS-friendly IPFS gateways
- [x] Automatic retry with gateway fallback
- [x] Simple metadata caching
- [x] Social media link extraction and icons
- [x] Image handling with IPFS support
- [x] Error handling without console spam
- [x] Non-blocking UI operations
- [x] Clean TypeScript implementation
### 🚫 Removed Features
- [x] Complex composable abstractions
- [x] Batch processing utilities
- [x] Server API proxy routes
- [x] Debugging console output
- [x] Exponential backoff (replaced with gateway rotation)
## Usage Examples
### Basic Metadata Fetching
```typescript
import { fetchTokenMetadata } from '../utils/ipfs';
const metadata = await fetchTokenMetadata('https://ipfs.io/ipfs/bafkreixxx');
if (metadata) {
console.log(metadata.name, metadata.symbol);
}
```
### Image Handling
```typescript
import { getTokenImage } from '../utils/ipfs';
const imageUrl = getTokenImage(metadata);
if (imageUrl) {
// Use imageUrl for img src
}
```
### Social Links
```typescript
import { extractSocialLinks } from '../utils/ipfs';
const socialLinks = extractSocialLinks(metadata);
socialLinks.forEach(link => {
console.log(link.type, link.url, link.icon);
});
```
## Testing and Validation
### Manual Testing Performed
- [x] IPFS metadata fetching from various URIs
- [x] Gateway fallback functionality
- [x] CORS compatibility across gateways
- [x] Image loading and fallback behavior
- [x] Social media link detection
- [x] Error handling and recovery
- [x] Cache functionality and statistics
### Known Working URIs
```
https://ipfs.io/ipfs/bafkreigr67ogup7ijve5mq7vh22nyydsvksfqtctxu3bdtsgs47uihlaka
https://ipfs.io/ipfs/bafkreido7xq6dx2m7nxlnoeoz562uapvpfs4yup2eyckerzvggylgttcoa
```
## Maintenance Notes
### Cache Management
```typescript
import { clearMetadataCache, getCacheStats } from '../utils/ipfs';
// Clear cache when needed
clearMetadataCache();
// Monitor cache usage
const stats = getCacheStats();
console.log(`Cache size: ${stats.size}, hits: ${stats.hits}`);
```
### Gateway Management
- Monitor gateway performance and update priority as needed
- Add new CORS-friendly gateways when available
- Remove unreliable gateways from the list
### Error Monitoring
- Monitor for new types of IPFS errors
- Update error handling as needed
- Track gateway success rates for optimization
---
**Last Updated**: December 22, 2024
**Status**: Production Ready ✅