import React, { Component, ErrorInfo, ReactNode } from 'react'; import { AlertTriangle, RefreshCw, Bug, Home } from 'lucide-react'; interface Props { children: ReactNode; fallback?: ReactNode; } interface State { hasError: boolean; error: Error | null; errorInfo: ErrorInfo | null; errorId: string; } class ErrorBoundary extends Component { public state: State = { hasError: false, error: null, errorInfo: null, errorId: '' }; public static getDerivedStateFromError(error: Error): Partial { // Gerar ID único para o erro const errorId = Date.now().toString(36) + Math.random().toString(36).substring(2); return { hasError: true, error, errorId }; } public componentDidCatch(error: Error, errorInfo: ErrorInfo) { this.setState({ error, errorInfo }); // Log do erro para monitoramento console.error('ErrorBoundary capturou um erro:', error, errorInfo); // Em produção, você enviaria isso para um serviço de monitoramento this.logErrorToService(error, errorInfo); } private logErrorToService = (error: Error, errorInfo: ErrorInfo) => { // Simular logging para serviço externo const errorData = { message: error.message, stack: error.stack, componentStack: errorInfo.componentStack, timestamp: new Date().toISOString(), userAgent: navigator.userAgent, url: window.location.href, errorId: this.state.errorId }; // Em produção, você faria algo como: // fetch('/api/log-error', { method: 'POST', body: JSON.stringify(errorData) }) localStorage.setItem(`error_${this.state.errorId}`, JSON.stringify(errorData)); }; private handleRetry = () => { this.setState({ hasError: false, error: null, errorInfo: null, errorId: '' }); }; private handleReload = () => { window.location.reload(); }; private copyErrorDetails = () => { const errorDetails = { error: this.state.error?.message, stack: this.state.error?.stack, componentStack: this.state.errorInfo?.componentStack, errorId: this.state.errorId, timestamp: new Date().toISOString() }; navigator.clipboard.writeText(JSON.stringify(errorDetails, null, 2)); }; public render() { if (this.state.hasError) { if (this.props.fallback) { return this.props.fallback; } return (
{/* Ícone de erro */}
{/* Título e descrição */}

Oops! Algo deu errado

Ocorreu um erro inesperado na aplicação. Nossa equipe foi notificada.

{/* Detalhes do erro (modo desenvolvimento) */} {process.env.NODE_ENV === 'development' && this.state.error && (
Detalhes do erro (desenvolvimento)
Erro: {this.state.error.message}
ID: {this.state.errorId}
{this.state.error.stack && (
Stack:
                          {this.state.error.stack}
                        
)}
)} {/* Informações do erro */}
ID do Erro
{this.state.errorId}
{/* Ações */}
{/* Dicas */}

Dicas para resolver:

  • • Verifique sua conexão com a internet
  • • Tente atualizar a página
  • • Limpe o cache do navegador
  • • Se o problema persistir, entre em contato conosco
{/* Informações técnicas */}
Lotomania Pro v1.0.0 • {new Date().toLocaleString('pt-BR')}
); } return this.props.children; } } // Hook para usar ErrorBoundary funcionalmente export const useErrorHandler = () => { const handleError = (error: Error, errorInfo?: any) => { console.error('Erro capturado:', error, errorInfo); // Em produção, enviar para serviço de monitoramento if (process.env.NODE_ENV === 'production') { // fetch('/api/log-error', ...) } }; return { handleError }; }; // Componente funcional para erros menores export const ErrorFallback: React.FC<{ error: Error; resetError: () => void; }> = ({ error, resetError }) => (

Erro no Componente

{error.message}

); export default ErrorBoundary;