diff --git a/check-vite-status.sh b/check-vite-status.sh new file mode 100644 index 00000000..c2d28fc3 --- /dev/null +++ b/check-vite-status.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# Quick Vite dev server status check + +echo "╔════════════════════════════════════════════════════════════╗" +echo "║ Vite Dev Server Status Check (Port 8021) ║" +echo "╚════════════════════════════════════════════════════════════╝" +echo "" + +# Check Docker container +echo "📦 Docker Container Status:" +if docker ps --filter "name=igny8_frontend" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -q igny8_frontend; then + docker ps --filter "name=igny8_frontend" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" +else + echo " ❌ Container 'igny8_frontend' not found or not running" +fi +echo "" + +# Check port +echo "🔌 Port 8021 Status:" +if netstat -tuln 2>/dev/null | grep -q ":8021" || ss -tuln 2>/dev/null | grep -q ":8021"; then + echo " ✅ Port 8021 is listening" + netstat -tuln 2>/dev/null | grep ":8021" || ss -tuln 2>/dev/null | grep ":8021" +else + echo " ❌ Port 8021 is not listening" +fi +echo "" + +# Test HTTP response +echo "🌐 HTTP Response Test:" +HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8021/ 2>/dev/null) +if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "304" ]; then + echo " ✅ Server responding (HTTP $HTTP_CODE)" +else + echo " ❌ Server not responding (HTTP $HTTP_CODE or connection failed)" +fi +echo "" + +# Check recent logs +echo "📋 Recent Container Logs (last 10 lines):" +docker logs igny8_frontend --tail 10 2>/dev/null || echo " ⚠️ Could not fetch logs" +echo "" + +echo "════════════════════════════════════════════════════════════" + diff --git a/frontend/src/components/debug/ResourceDebugOverlay.tsx b/frontend/src/components/debug/ResourceDebugOverlay.tsx index f67df232..a77bd5a5 100644 --- a/frontend/src/components/debug/ResourceDebugOverlay.tsx +++ b/frontend/src/components/debug/ResourceDebugOverlay.tsx @@ -93,8 +93,9 @@ export default function ResourceDebugOverlay({ enabled }: ResourceDebugOverlayPr const requestId = response.headers.get('X-Resource-Tracking-ID'); if (requestId) { requestIdRef.current = requestId; - // Fetch metrics after a short delay to ensure backend has stored them - setTimeout(() => fetchRequestMetrics(requestId), 200); + // Fetch metrics after a delay to ensure backend has stored them + // Use a slightly longer delay to avoid race conditions + setTimeout(() => fetchRequestMetrics(requestId), 300); } return response; @@ -111,7 +112,7 @@ export default function ResourceDebugOverlay({ enabled }: ResourceDebugOverlayPr }, [enabled, isAdminOrDeveloper]); // Fetch metrics for a request - use fetchAPI to get proper authentication handling - const fetchRequestMetrics = async (requestId: string) => { + const fetchRequestMetrics = async (requestId: string, retryCount = 0) => { try { // Use fetchAPI which handles token refresh and authentication properly // But we need to use native fetch to avoid interception loop @@ -135,7 +136,10 @@ export default function ResourceDebugOverlay({ enabled }: ResourceDebugOverlayPr if (response.ok) { const data = await response.json(); - console.log('Fetched metrics for request:', requestId, data); // Debug log + // Only log in debug mode to reduce console noise + if (import.meta.env.DEV) { + console.debug('Fetched metrics for request:', requestId, data); + } metricsRef.current = [...metricsRef.current, data]; setMetrics([...metricsRef.current]); } else if (response.status === 401) { @@ -166,11 +170,19 @@ export default function ResourceDebugOverlay({ enabled }: ResourceDebugOverlayPr } // Silently ignore 401 errors - user might not be authenticated } else if (response.status === 404) { - // Metrics not found or expired - this is expected, silently ignore - // Metrics expire after 5 minutes, so 404 is normal for older requests + // Metrics not found - could be race condition, retry once after short delay + if (retryCount === 0) { + // First attempt failed, retry once after 200ms (middleware might still be storing) + setTimeout(() => fetchRequestMetrics(requestId, 1), 200); + return; + } + // Second attempt also failed - metrics truly not available + // This is expected: metrics expired (5min TTL), request wasn't tracked, or middleware error + // Silently ignore - no need to log or show error return; } else { - console.warn('Failed to fetch metrics:', response.status, response.statusText); + // Only log non-404/401 errors (500, 403, etc.) + console.warn('Failed to fetch metrics:', response.status, response.statusText, 'for request:', requestId); } } catch (error) { // Only log non-network errors diff --git a/frontend/src/layout/AppLayout.tsx b/frontend/src/layout/AppLayout.tsx index 855556af..f2b6fbbc 100644 --- a/frontend/src/layout/AppLayout.tsx +++ b/frontend/src/layout/AppLayout.tsx @@ -32,14 +32,15 @@ const LayoutContent: React.FC = () => { trackLoading('site-loading', true); // Add timeout to prevent infinite loading + // Match API timeout (30s) + buffer for network delays const timeoutId = setTimeout(() => { if (isLoadingSite.current) { - console.error('AppLayout: Site loading timeout after 10 seconds'); + console.error('AppLayout: Site loading timeout after 35 seconds'); trackLoading('site-loading', false); isLoadingSite.current = false; addError(new Error('Site loading timeout - check network connection'), 'AppLayout.loadActiveSite'); } - }, 10000); + }, 35000); // 35 seconds to match API timeout (30s) + buffer loadActiveSite() .catch((error) => { @@ -69,14 +70,15 @@ const LayoutContent: React.FC = () => { trackLoading('sector-loading', true); // Add timeout to prevent infinite loading + // Match API timeout (30s) + buffer for network delays const timeoutId = setTimeout(() => { if (isLoadingSector.current) { - console.error('AppLayout: Sector loading timeout after 10 seconds'); + console.error('AppLayout: Sector loading timeout after 35 seconds'); trackLoading('sector-loading', false); isLoadingSector.current = false; addError(new Error('Sector loading timeout - check network connection'), 'AppLayout.loadSectorsForSite'); } - }, 10000); + }, 35000); // 35 seconds to match API timeout (30s) + buffer loadSectorsForSite(currentSiteId) .catch((error) => {