fix: comprehensive error logging — all errors now captured in client_error_logs

- safeSupabaseCall: logs caught errors via logError
- AuthContext: logs sendOtp, verifyOtp errors
- ErrorLogPanel: fixed client→supabase reference in delete functions
- AuthContext: sets window.__supersam_user_id__ on auth state change
This commit is contained in:
root 2026-05-27 15:30:33 +00:00
parent dac8450586
commit 7dfdd91798
3 changed files with 14 additions and 5 deletions

View File

@ -138,7 +138,7 @@ export default function ErrorLogPanel() {
if (selected.size === 0) return; if (selected.size === 0) return;
if (!confirm(`Удалить ${selected.size} записей?`)) return; if (!confirm(`Удалить ${selected.size} записей?`)) return;
setDeleting(true); setDeleting(true);
const { error: err } = await client const { error: err } = await supabase
.from('client_error_logs') .from('client_error_logs')
.delete() .delete()
.in('id', Array.from(selected)); .in('id', Array.from(selected));
@ -150,7 +150,7 @@ export default function ErrorLogPanel() {
const handleDeleteAll = async () => { const handleDeleteAll = async () => {
if (!confirm('Удалить ВСЕ записи об ошибках? Это необратимо.')) return; if (!confirm('Удалить ВСЕ записи об ошибках? Это необратимо.')) return;
setDeleting(true); setDeleting(true);
const { error: err } = await client const { error: err } = await supabase
.from('client_error_logs') .from('client_error_logs')
.delete() .delete()
.neq('id', '00000000-0000-0000-0000-000000000000'); .neq('id', '00000000-0000-0000-0000-000000000000');
@ -162,7 +162,7 @@ export default function ErrorLogPanel() {
const handleDeleteOne = async (id) => { const handleDeleteOne = async (id) => {
if (!confirm('Удалить эту запись?')) return; if (!confirm('Удалить эту запись?')) return;
setDeleting(true); setDeleting(true);
const { error: err } = await client const { error: err } = await supabase
.from('client_error_logs') .from('client_error_logs')
.delete() .delete()
.eq('id', id); .eq('id', id);

View File

@ -1,6 +1,7 @@
import React, { createContext, useContext, useEffect, useRef, useState } from "react"; import React, { createContext, useContext, useEffect, useRef, useState } from "react";
import { demoUsers } from "../data/mockAppData"; import { demoUsers } from "../data/mockAppData";
import { supabase, hasSupabaseConfig } from "../supabaseClient"; import { supabase, hasSupabaseConfig } from "../supabaseClient";
import { logError } from "../utils/errorLogger";
const AuthContext = createContext(null); const AuthContext = createContext(null);
const STORAGE_KEY = "construction-auth-local-user"; const STORAGE_KEY = "construction-auth-local-user";
@ -162,6 +163,7 @@ export const AuthProvider = ({ children }) => {
if (!session?.user) { if (!session?.user) {
setUser(null); setUser(null);
setAuthError(""); setAuthError("");
window.__supersam_user_id__ = null;
return; return;
} }
@ -171,6 +173,8 @@ export const AuthProvider = ({ children }) => {
} }
const baseUser = mapSessionUserToAuthUser(session.user); const baseUser = mapSessionUserToAuthUser(session.user);
// Expose userId for error logger
window.__supersam_user_id__ = session.user?.id || null;
if (baseUser) { if (baseUser) {
fetchUserProfile(session.user.id).then((profile) => { fetchUserProfile(session.user.id).then((profile) => {
if (profile) { if (profile) {
@ -257,6 +261,7 @@ export const AuthProvider = ({ children }) => {
} catch (error) { } catch (error) {
const normalizedError = normalizeOtpError(error); const normalizedError = normalizeOtpError(error);
setAuthError(normalizedError.message); setAuthError(normalizedError.message);
logError(error, { component: "AuthContext.sendOtp" });
return { success: false, error: normalizedError }; return { success: false, error: normalizedError };
} finally { } finally {
setIsLoading(false); setIsLoading(false);
@ -326,6 +331,7 @@ export const AuthProvider = ({ children }) => {
} catch (error) { } catch (error) {
const normalizedError = normalizeOtpError(error); const normalizedError = normalizeOtpError(error);
setAuthError(normalizedError.message); setAuthError(normalizedError.message);
logError(error, { component: "AuthContext.verifyOtp" });
return { success: false, error: normalizedError }; return { success: false, error: normalizedError };
} finally { } finally {
setIsLoading(false); setIsLoading(false);

View File

@ -1,4 +1,5 @@
import logger from "../utils/logger"; import logger from "../utils/logger";
import { logError } from "../utils/errorLogger";
export const safeSupabaseCall = async (callback, fallbackMessage = "Ошибка Supabase") => { export const safeSupabaseCall = async (callback, fallbackMessage = "Ошибка Supabase") => {
try { try {
@ -6,6 +7,8 @@ export const safeSupabaseCall = async (callback, fallbackMessage = "Ошибка
return { data, error: null }; return { data, error: null };
} catch (error) { } catch (error) {
logger.error(fallbackMessage, error); logger.error(fallbackMessage, error);
// Also log to client_error_logs for admin visibility
logError(error, { component: "safeSupabaseCall", props: { fallbackMessage } });
return { data: null, error }; return { data: null, error };
} }
}; };