feat: log de errores para el admin (backend + frontend)
Panel nuevo en Configuracion ("Errores del sistema", solo superadmin): errores de backend
(excepciones 500 no manejadas, con stack/ruta/metodo/usuario) y de frontend (errores JS y
promesas sin catch en el navegador del usuario, antes invisibles para cualquiera mas alla de esa
persona). Filtro por origen, boton para limpiar el historial.
Error Boundary de React: si algo rompe el render, ya no queda pantalla en blanco -- aviso simple
con boton de recargar, y el error queda reportado igual.
Nuevo error_logs (tabla, se recorta sola a 1000 filas) + GET/DELETE /api/error-logs (superadmin)
+ POST /api/error-logs (publico, rate-limited, para reportar incluso sin sesion).
Probado de punta a punta en dev: error real de backend (500) capturado con stack completo y
usuario correcto, error JS global y promesa rechazada capturados desde el navegador, panel
muestra ambos y el boton de limpiar funciona. Se encontro y corrigio un bug real en el camino: la
identificacion de usuario opcional leia jwt.payload.id en vez de .sub (como realmente lo firma
auth/service.js), asi que nunca identificaba a nadie.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+29
-26
@@ -4,6 +4,7 @@ import { UiProvider } from '../context/ui-context.jsx';
|
||||
import { BrandingProvider } from '../context/branding-context.jsx';
|
||||
import { ContentDialogHost } from '../components/ContentDialog.jsx';
|
||||
import { ToastHost } from '../components/ToastHost.jsx';
|
||||
import { ErrorBoundary } from '../components/ErrorBoundary.jsx';
|
||||
import { ProtectedRoute } from './ProtectedRoute.jsx';
|
||||
import AppShell from './AppShell.jsx';
|
||||
import LoginPage from '../pages/Login/LoginPage.jsx';
|
||||
@@ -21,31 +22,33 @@ import RecurringTasksPage from '../pages/RecurringTasks/RecurringTasksPage.jsx';
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<BrandingProvider>
|
||||
<UiProvider>
|
||||
<AuthProvider>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/registro" element={<RegisterPage />} />
|
||||
<Route path="/verificar-correo" element={<VerifyEmailPage />} />
|
||||
<Route path="/olvide-clave" element={<ForgotPasswordPage />} />
|
||||
<Route path="/restablecer-clave" element={<ResetPasswordPage />} />
|
||||
<Route path="/aceptar-invitacion" element={<AcceptInvitePage />} />
|
||||
<Route path="/" element={<ProtectedRoute><AppShell /></ProtectedRoute>}>
|
||||
<Route index element={<DashboardPage />} />
|
||||
<Route path="proyectos" element={<ProyectosPage />} />
|
||||
<Route path="proyectos/:id" element={<ProyectoDetallePage />} />
|
||||
<Route path="tareas-recurrentes" element={<RecurringTasksPage />} />
|
||||
<Route path="organizacion" element={<OrganizacionPage />} />
|
||||
<Route path="configuracion" element={<ConfiguracionPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
<ContentDialogHost />
|
||||
<ToastHost />
|
||||
</AuthProvider>
|
||||
</UiProvider>
|
||||
</BrandingProvider>
|
||||
<ErrorBoundary>
|
||||
<BrandingProvider>
|
||||
<UiProvider>
|
||||
<AuthProvider>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/registro" element={<RegisterPage />} />
|
||||
<Route path="/verificar-correo" element={<VerifyEmailPage />} />
|
||||
<Route path="/olvide-clave" element={<ForgotPasswordPage />} />
|
||||
<Route path="/restablecer-clave" element={<ResetPasswordPage />} />
|
||||
<Route path="/aceptar-invitacion" element={<AcceptInvitePage />} />
|
||||
<Route path="/" element={<ProtectedRoute><AppShell /></ProtectedRoute>}>
|
||||
<Route index element={<DashboardPage />} />
|
||||
<Route path="proyectos" element={<ProyectosPage />} />
|
||||
<Route path="proyectos/:id" element={<ProyectoDetallePage />} />
|
||||
<Route path="tareas-recurrentes" element={<RecurringTasksPage />} />
|
||||
<Route path="organizacion" element={<OrganizacionPage />} />
|
||||
<Route path="configuracion" element={<ConfiguracionPage />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
<ContentDialogHost />
|
||||
<ToastHost />
|
||||
</AuthProvider>
|
||||
</UiProvider>
|
||||
</BrandingProvider>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user