'use client'; import { ApiError } from '@/lib/api/base/ApiError'; import { connectionMonitor } from '@/lib/api/base/ApiConnectionMonitor'; import { CircuitBreakerRegistry } from '@/lib/api/base/RetryHandler'; import { useState, useEffect } from 'react'; import { X, RefreshCw, Copy, Terminal, Activity, AlertTriangle } from 'lucide-react'; interface DevErrorPanelProps { error: ApiError; onReset: () => void; } /** * Developer-focused error panel with detailed debugging information */ export function DevErrorPanel({ error, onReset }: DevErrorPanelProps) { const [connectionStatus, setConnectionStatus] = useState(connectionMonitor.getHealth()); const [circuitBreakers, setCircuitBreakers] = useState(CircuitBreakerRegistry.getInstance().getStatus()); const [copied, setCopied] = useState(false); useEffect(() => { // Update status on mount const health = connectionMonitor.getHealth(); setConnectionStatus(health); setCircuitBreakers(CircuitBreakerRegistry.getInstance().getStatus()); // Listen for status changes const handleStatusChange = () => { setConnectionStatus(connectionMonitor.getHealth()); setCircuitBreakers(CircuitBreakerRegistry.getInstance().getStatus()); }; connectionMonitor.on('success', handleStatusChange); connectionMonitor.on('failure', handleStatusChange); connectionMonitor.on('connected', handleStatusChange); connectionMonitor.on('disconnected', handleStatusChange); connectionMonitor.on('degraded', handleStatusChange); return () => { connectionMonitor.off('success', handleStatusChange); connectionMonitor.off('failure', handleStatusChange); connectionMonitor.off('connected', handleStatusChange); connectionMonitor.off('disconnected', handleStatusChange); connectionMonitor.off('degraded', handleStatusChange); }; }, []); const copyToClipboard = async () => { const debugInfo = { error: { type: error.type, message: error.message, context: error.context, stack: error.stack, }, connection: connectionStatus, circuitBreakers, timestamp: new Date().toISOString(), userAgent: navigator.userAgent, url: window.location.href, }; try { await navigator.clipboard.writeText(JSON.stringify(debugInfo, null, 2)); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch (err) { // Silent failure for clipboard operations } }; const triggerHealthCheck = async () => { await connectionMonitor.performHealthCheck(); setConnectionStatus(connectionMonitor.getHealth()); }; const resetCircuitBreakers = () => { CircuitBreakerRegistry.getInstance().resetAll(); setCircuitBreakers(CircuitBreakerRegistry.getInstance().getStatus()); }; const getSeverityColor = (type: string) => { switch (error.getSeverity()) { case 'error': return 'bg-red-500/20 text-red-400 border-red-500/40'; case 'warn': return 'bg-yellow-500/20 text-yellow-400 border-yellow-500/40'; case 'info': return 'bg-blue-500/20 text-blue-400 border-blue-500/40'; default: return 'bg-gray-500/20 text-gray-400 border-gray-500/40'; } }; const reliability = connectionMonitor.getReliability(); return (
{/* Header */}

API Error Debug Panel

{error.type}
{/* Error Details */}
Error Details
Type: {error.type}
Message: {error.message}
Endpoint: {error.context.endpoint || 'N/A'}
Method: {error.context.method || 'N/A'}
Status: {error.context.statusCode || 'N/A'}
Retry Count: {error.context.retryCount || 0}
Timestamp: {error.context.timestamp}
Retryable: {error.isRetryable() ? 'Yes' : 'No'}
Connectivity: {error.isConnectivityIssue() ? 'Yes' : 'No'}
{error.context.troubleshooting && (
Troubleshoot: {error.context.troubleshooting}
)}
{/* Connection Status */}
Connection Health
Status: {connectionStatus.status.toUpperCase()}
Reliability: {reliability.toFixed(2)}%
Total Requests: {connectionStatus.totalRequests}
Successful: {connectionStatus.successfulRequests}
Failed: {connectionStatus.failedRequests}
Consecutive Failures: {connectionStatus.consecutiveFailures}
Avg Response: {connectionStatus.averageResponseTime.toFixed(2)}ms
Last Check: {connectionStatus.lastCheck?.toLocaleTimeString() || 'Never'}
{/* Right Column */}
{/* Circuit Breakers */}
Circuit Breakers
{Object.keys(circuitBreakers).length === 0 ? (
No circuit breakers active
) : (
{Object.entries(circuitBreakers).map(([endpoint, status]) => (
{endpoint} {status.state} {status.failures} failures
))}
)}
{/* Actions */}
Actions
{/* Quick Fixes */}
Quick Fixes
Common solutions:
  • Check API server is running
  • Verify CORS configuration
  • Check environment variables
  • Review network connectivity
  • Check API rate limits
{/* Raw Error */}
Raw Error
                  {JSON.stringify({
                    type: error.type,
                    message: error.message,
                    context: error.context,
                  }, null, 2)}
                
{/* Console Output */}
Console Output
{'>'} {error.getDeveloperMessage()}
Check browser console for full stack trace and additional debug info.
); }