+
+ Something went wrong
+
+
+ An unexpected error occurred. You can try again or refresh the page.
+
+
+
+ Error details
+
+
+ {this.state.error.message}
+ {this.state.error.stack ? `\n\n${this.state.error.stack}` : ''}
+
+
+
+
+ );
+ }
+
+ return this.props.children;
+ }
+}
+
+export default ErrorBoundary;
diff --git a/frontend/src/hooks/useAuth.ts b/frontend/src/hooks/useAuth.ts
index 9e7a656..e0cc6cd 100644
--- a/frontend/src/hooks/useAuth.ts
+++ b/frontend/src/hooks/useAuth.ts
@@ -4,14 +4,19 @@ import { useCurrentUser } from '@/api/hooks';
export function useAuth() {
const store = useAuthStore();
- const { data, isLoading, isError } = useCurrentUser();
+ const { data, isLoading, isError, error } = useCurrentUser();
useEffect(() => {
if (isError) {
- store.setAuthenticated(false);
- store.setUser(null);
+ const status = (error as any)?.status || 0;
+ // Only logout on 401 Unauthorized — other errors are transient
+ if (status === 401) {
+ store.setAuthenticated(false);
+ store.setUser(null);
+ }
+ // For 403, 500, network errors: keep session, don't logout
}
- }, [isError, store]);
+ }, [isError, error, store]);
return {
user: store.user,
diff --git a/frontend/src/utils/errorLogger.ts b/frontend/src/utils/errorLogger.ts
new file mode 100644
index 0000000..1c1e148
--- /dev/null
+++ b/frontend/src/utils/errorLogger.ts
@@ -0,0 +1,106 @@
+/**
+ * Global Error Logger
+ *
+ * Centralized error collection and reporting.
+ * - Always logs to console.error
+ * - Optionally POSTs to /api/v1/errors (silently fails if endpoint unavailable)
+ * - Buffers errors in sessionStorage (ring buffer, max 50)
+ */
+
+const STORAGE_KEY = 'leocrm_error_buffer';
+const MAX_BUFFER_SIZE = 50;
+
+interface ErrorEntry {
+ timestamp: string;
+ message: string;
+ stack?: string;
+ context?: Record