'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 (
{JSON.stringify({
type: error.type,
message: error.message,
context: error.context,
}, null, 2)}