From 00c156b4fd5315dea068c37d8be6ac3146f12554 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 25 Feb 2026 11:08:29 -0500 Subject: [PATCH] fix: add null guards to Analytics component preventing white screen API responses with missing nested fields (sessionStats, agentStats, qualityStats, averageProcessingTime, averageApiCalls) caused .toFixed() and .map() to crash on undefined. Added ?? null coalescing throughout. Co-Authored-By: Claude Opus 4.6 --- frontend/src/components/Analytics.tsx | 44 +++++++++++++-------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/frontend/src/components/Analytics.tsx b/frontend/src/components/Analytics.tsx index efd32bc..86f2d1b 100644 --- a/frontend/src/components/Analytics.tsx +++ b/frontend/src/components/Analytics.tsx @@ -92,8 +92,8 @@ const Analytics: React.FC = () => { setProcessingStats(stats); setHealthStatus(health); } catch (err) { - setError('Failed to load analytics data'); console.error('Analytics loading error:', err); + setError('Failed to load analytics data. Some endpoints may not be available.'); } finally { setLoading(false); } @@ -164,7 +164,7 @@ const Analytics: React.FC = () => { {/* System Health Overview */} - {healthStatus && ( + {healthStatus?.overall && (

System Health

@@ -177,25 +177,25 @@ const Analytics: React.FC = () => { Overall Status

- {healthStatus.status.charAt(0).toUpperCase() + healthStatus.status.slice(1)} + {healthStatus.status?.charAt(0).toUpperCase() + healthStatus.status?.slice(1)}

Success Rate

- {(healthStatus.overall.successRate * 100).toFixed(1)}% + {((healthStatus.overall.successRate ?? 0) * 100).toFixed(1)}%

Avg Processing Time

- {formatTime(healthStatus.overall.averageProcessingTime)} + {formatTime(healthStatus.overall.averageProcessingTime ?? 0)}

Active Sessions

- {healthStatus.overall.activeSessions} + {healthStatus.overall.activeSessions ?? 0}

@@ -213,24 +213,24 @@ const Analytics: React.FC = () => {
Chunking - {processingStats.totalDocuments > 0 - ? ((processingStats.chunkingSuccess / processingStats.totalDocuments) * 100).toFixed(1) + {processingStats.totalDocuments > 0 + ? (((processingStats.chunkingSuccess ?? 0) / processingStats.totalDocuments) * 100).toFixed(1) : 0}%
RAG - {processingStats.totalDocuments > 0 - ? ((processingStats.ragSuccess / processingStats.totalDocuments) * 100).toFixed(1) + {processingStats.totalDocuments > 0 + ? (((processingStats.ragSuccess ?? 0) / processingStats.totalDocuments) * 100).toFixed(1) : 0}%
Agentic RAG - {processingStats.totalDocuments > 0 - ? ((processingStats.agenticRagSuccess / processingStats.totalDocuments) * 100).toFixed(1) + {processingStats.totalDocuments > 0 + ? (((processingStats.agenticRagSuccess ?? 0) / processingStats.totalDocuments) * 100).toFixed(1) : 0}%
@@ -241,15 +241,15 @@ const Analytics: React.FC = () => {
Chunking - {formatTime(processingStats.averageProcessingTime.chunking)} + {formatTime(processingStats.averageProcessingTime?.chunking ?? 0)}
RAG - {formatTime(processingStats.averageProcessingTime.rag)} + {formatTime(processingStats.averageProcessingTime?.rag ?? 0)}
Agentic RAG - {formatTime(processingStats.averageProcessingTime.agenticRag)} + {formatTime(processingStats.averageProcessingTime?.agenticRag ?? 0)}
@@ -258,15 +258,15 @@ const Analytics: React.FC = () => {
Chunking - {processingStats.averageApiCalls.chunking.toFixed(1)} + {(processingStats.averageApiCalls?.chunking ?? 0).toFixed(1)}
RAG - {processingStats.averageApiCalls.rag.toFixed(1)} + {(processingStats.averageApiCalls?.rag ?? 0).toFixed(1)}
Agentic RAG - {processingStats.averageApiCalls.agenticRag.toFixed(1)} + {(processingStats.averageApiCalls?.agenticRag ?? 0).toFixed(1)}
@@ -291,7 +291,7 @@ const Analytics: React.FC = () => { - {analyticsData.sessionStats.map((stat, index) => ( + {(analyticsData.sessionStats ?? []).map((stat, index) => ( {new Date(stat.date).toLocaleDateString()} @@ -318,7 +318,7 @@ const Analytics: React.FC = () => {

Agent Performance

- {analyticsData.agentStats.map((agent, index) => ( + {(analyticsData.agentStats ?? []).map((agent, index) => (

{agent.agent_name.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())} @@ -342,7 +342,7 @@ const Analytics: React.FC = () => {

Avg Retries: - {parseFloat(agent.avg_retries).toFixed(1)} + {(parseFloat(agent.avg_retries) || 0).toFixed(1)}
@@ -356,7 +356,7 @@ const Analytics: React.FC = () => {

Quality Metrics

- {analyticsData.qualityStats.map((metric, index) => ( + {(analyticsData.qualityStats ?? []).map((metric, index) => (

{metric.metric_type.charAt(0).toUpperCase() + metric.metric_type.slice(1)}