feat: Complete app-wide error coverage

This commit is contained in:
gpt-engineer-app[bot]
2025-11-04 19:58:20 +00:00
parent d9bd7c1616
commit a649906b61
22 changed files with 111 additions and 57 deletions

View File

@@ -6,7 +6,7 @@
*/ */
import { z } from 'zod'; import { z } from 'zod';
import { logger } from '@/lib/logger'; import { handleError } from '@/lib/errorHandler';
// Profile schema (matches database JSONB structure) // Profile schema (matches database JSONB structure)
const ProfileSchema = z.object({ const ProfileSchema = z.object({
@@ -101,8 +101,11 @@ export function validateModerationItems(data: unknown): {
const result = ModerationItemArraySchema.safeParse(data); const result = ModerationItemArraySchema.safeParse(data);
if (!result.success) { if (!result.success) {
logger.error('❌ Data validation failed', { handleError(result.error, {
errors: result.error.issues.slice(0, 5) // Log first 5 issues action: 'Data validation failed',
metadata: {
errors: result.error.issues.slice(0, 5)
}
}); });
return { return {

View File

@@ -5,7 +5,7 @@
*/ */
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import { logger } from './logger'; import { handleError, handleNonCriticalError } from './errorHandler';
export interface SubmissionMetadataInsert { export interface SubmissionMetadataInsert {
submission_id: string; submission_id: string;
@@ -37,7 +37,10 @@ export async function writeSubmissionMetadata(
.insert(entries); .insert(entries);
if (error) { if (error) {
logger.error('Failed to write submission metadata', { error, submissionId }); handleError(error, {
action: 'Write submission metadata',
metadata: { submissionId }
});
throw error; throw error;
} }
} }
@@ -56,7 +59,10 @@ export async function readSubmissionMetadata(
.order('display_order'); .order('display_order');
if (error) { if (error) {
logger.error('Failed to read submission metadata', { error, submissionId }); handleNonCriticalError(error, {
action: 'Read submission metadata',
metadata: { submissionId }
});
return {}; return {};
} }

View File

@@ -1,6 +1,6 @@
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import type { ParkSubmissionData, RideSubmissionData, CompanySubmissionData, RideModelSubmissionData } from '@/types/submission-data'; import type { ParkSubmissionData, RideSubmissionData, CompanySubmissionData, RideModelSubmissionData } from '@/types/submission-data';
import { logger } from './logger'; import { handleNonCriticalError } from './errorHandler';
import { import {
randomInt, randomInt,
randomFloat, randomFloat,
@@ -352,12 +352,18 @@ export async function clearTestData(): Promise<{ deleted: number }> {
.neq('id', '00000000-0000-0000-0000-000000000000'); // Delete all records .neq('id', '00000000-0000-0000-0000-000000000000'); // Delete all records
if (registryError) { if (registryError) {
logger.error('Error clearing test data registry', { error: registryError }); handleNonCriticalError(registryError, {
action: 'Clear test data registry',
metadata: { operation: 'clearTestData' }
});
} }
return { deleted: submissionCount }; return { deleted: submissionCount };
} catch (error: unknown) { } catch (error: unknown) {
logger.error('Error clearing test data', { error: error instanceof Error ? error.message : String(error) }); handleNonCriticalError(error, {
action: 'Clear test data',
metadata: { operation: 'clearTestData' }
});
throw error; throw error;
} }
} }

View File

@@ -11,7 +11,7 @@
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import type { EntityType } from '@/types/versioning'; import type { EntityType } from '@/types/versioning';
import { createTableQuery } from './supabaseHelpers'; import { createTableQuery } from './supabaseHelpers';
import { logger } from './logger'; import { handleNonCriticalError } from './errorHandler';
/** /**
* Manually trigger cleanup of old versions for a specific entity type * Manually trigger cleanup of old versions for a specific entity type
@@ -38,7 +38,10 @@ export async function cleanupVersions(
}); });
if (error) { if (error) {
logger.error('Version cleanup failed', { error, entityType, keepCount }); handleNonCriticalError(error, {
action: 'Version cleanup',
metadata: { entityType, keepCount }
});
return 0; return 0;
} }
@@ -98,7 +101,10 @@ export async function getVersionStats(
const { data, error } = result; const { data, error } = result;
if (error || !data) { if (error || !data) {
logger.error('Failed to fetch version stats', { error, entityType, entityId }); handleNonCriticalError(error || new Error('No data returned'), {
action: 'Fetch version stats',
metadata: { entityType, entityId }
});
return null; return null;
} }

View File

@@ -1,5 +1,5 @@
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import { logger } from './logger'; import { handleNonCriticalError } from './errorHandler';
// Generate anonymous session hash (no PII) // Generate anonymous session hash (no PII)
function getSessionHash(): string { function getSessionHash(): string {
@@ -41,6 +41,9 @@ export async function trackPageView(
}); });
} catch (error: unknown) { } catch (error: unknown) {
// Fail silently - don't break the page if tracking fails // Fail silently - don't break the page if tracking fails
logger.error('Failed to track page view', { entityType, entityId }); handleNonCriticalError(error, {
action: 'Track page view',
metadata: { entityType, entityId }
});
} }
} }

View File

@@ -12,7 +12,7 @@ import { ArrowLeft, MapPin, Star, Globe, Calendar, Edit, Ruler } from 'lucide-re
import { Company } from '@/types/database'; import { Company } from '@/types/database';
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import { DesignerPhotoGallery } from '@/components/companies/DesignerPhotoGallery'; import { DesignerPhotoGallery } from '@/components/companies/DesignerPhotoGallery';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
// Lazy load admin form // Lazy load admin form
const DesignerForm = lazy(() => import('@/components/admin/DesignerForm').then(m => ({ default: m.DesignerForm }))); const DesignerForm = lazy(() => import('@/components/admin/DesignerForm').then(m => ({ default: m.DesignerForm })));
@@ -82,7 +82,10 @@ export default function DesignerDetail() {
fetchStatistics(data.id); fetchStatistics(data.id);
} }
} catch (error) { } catch (error) {
logger.error('Error fetching designer', { error }); handleNonCriticalError(error, {
action: 'Fetch designer',
metadata: { slug }
});
} finally { } finally {
setLoading(false); setLoading(false);
} }
@@ -109,7 +112,10 @@ export default function DesignerDetail() {
if (photosError) throw photosError; if (photosError) throw photosError;
setTotalPhotos(photosCount || 0); setTotalPhotos(photosCount || 0);
} catch (error) { } catch (error) {
logger.error('Error fetching statistics', { error }); handleNonCriticalError(error, {
action: 'Fetch designer statistics',
metadata: { designerId }
});
} finally { } finally {
setStatsLoading(false); setStatsLoading(false);
} }

View File

@@ -17,7 +17,7 @@ import { toast } from '@/hooks/use-toast';
import { useAuthModal } from '@/hooks/useAuthModal'; import { useAuthModal } from '@/hooks/useAuthModal';
import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useDocumentTitle } from '@/hooks/useDocumentTitle';
import { useOpenGraph } from '@/hooks/useOpenGraph'; import { useOpenGraph } from '@/hooks/useOpenGraph';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
export default function DesignerRides() { export default function DesignerRides() {
const { designerSlug } = useParams<{ designerSlug: string }>(); const { designerSlug } = useParams<{ designerSlug: string }>();
@@ -91,7 +91,10 @@ export default function DesignerRides() {
setRides((ridesData || []) as any); setRides((ridesData || []) as any);
} }
} catch (error) { } catch (error) {
logger.error('Error fetching data', { error }); handleNonCriticalError(error, {
action: 'Fetch designer rides',
metadata: { designerSlug }
});
} finally { } finally {
setLoading(false); setLoading(false);
} }

View File

@@ -18,7 +18,7 @@ import { DesignerCard } from '@/components/designers/DesignerCard';
import { DesignerListView } from '@/components/designers/DesignerListView'; import { DesignerListView } from '@/components/designers/DesignerListView';
import { DesignerForm } from '@/components/admin/DesignerForm'; import { DesignerForm } from '@/components/admin/DesignerForm';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
import { useUserRole } from '@/hooks/useUserRole'; import { useUserRole } from '@/hooks/useUserRole';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
import { submitCompanyCreation } from '@/lib/companyHelpers'; import { submitCompanyCreation } from '@/lib/companyHelpers';
@@ -89,7 +89,10 @@ export default function Designers() {
const { data } = await query; const { data } = await query;
setCompanies(data || []); setCompanies(data || []);
} catch (error) { } catch (error) {
logger.error('Error fetching companies', { error }); handleNonCriticalError(error, {
action: 'Fetch designers',
metadata: { page: 'designers' }
});
} finally { } finally {
setLoading(false); setLoading(false);
} }

View File

@@ -3,7 +3,7 @@ import { useNavigate } from "react-router-dom";
import { supabase } from "@/lib/supabaseClient"; import { supabase } from "@/lib/supabaseClient";
import { authStorage } from "@/lib/authStorage"; import { authStorage } from "@/lib/authStorage";
import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useDocumentTitle } from '@/hooks/useDocumentTitle';
import { logger } from '@/lib/logger'; import { handleError } from '@/lib/errorHandler';
/** /**
* ForceLogout - Hidden endpoint for completely clearing auth session * ForceLogout - Hidden endpoint for completely clearing auth session
@@ -16,26 +16,23 @@ const ForceLogout = () => {
useEffect(() => { useEffect(() => {
const performFullLogout = async () => { const performFullLogout = async () => {
logger.info('[ForceLogout] Starting complete auth cleanup');
try { try {
// 1. Sign out from Supabase // 1. Sign out from Supabase
logger.info('[ForceLogout] Signing out from Supabase');
await supabase.auth.signOut(); await supabase.auth.signOut();
// 2. Clear all auth-related storage // 2. Clear all auth-related storage
logger.info('[ForceLogout] Clearing all auth storage');
authStorage.clearAll(); authStorage.clearAll();
// 3. Brief delay to ensure cleanup completes // 3. Brief delay to ensure cleanup completes
await new Promise(resolve => setTimeout(resolve, 500)); await new Promise(resolve => setTimeout(resolve, 500));
logger.info('[ForceLogout] Auth cleanup complete, redirecting to home');
// 4. Redirect to home page // 4. Redirect to home page
navigate('/', { replace: true }); navigate('/', { replace: true });
} catch (error) { } catch (error) {
logger.error('[ForceLogout] Error during logout', { error }); handleError(error, {
action: 'Force logout',
metadata: { operation: 'forceLogout' }
});
// Still redirect even if there's an error // Still redirect even if there's an error
navigate('/', { replace: true }); navigate('/', { replace: true });
} }

View File

@@ -13,7 +13,7 @@ import { ArrowLeft, MapPin, Star, Globe, Calendar, Edit, Factory, FerrisWheel }
import { Company } from '@/types/database'; import { Company } from '@/types/database';
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import { ManufacturerPhotoGallery } from '@/components/companies/ManufacturerPhotoGallery'; import { ManufacturerPhotoGallery } from '@/components/companies/ManufacturerPhotoGallery';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
// Lazy load admin form // Lazy load admin form
const ManufacturerForm = lazy(() => import('@/components/admin/ManufacturerForm').then(m => ({ default: m.ManufacturerForm }))); const ManufacturerForm = lazy(() => import('@/components/admin/ManufacturerForm').then(m => ({ default: m.ManufacturerForm })));
@@ -83,7 +83,10 @@ export default function ManufacturerDetail() {
fetchStatistics(data.id); fetchStatistics(data.id);
} }
} catch (error) { } catch (error) {
logger.error('Error fetching manufacturer', { error }); handleNonCriticalError(error, {
action: 'Fetch manufacturer',
metadata: { slug }
});
} finally { } finally {
setLoading(false); setLoading(false);
} }
@@ -119,7 +122,10 @@ export default function ManufacturerDetail() {
if (photosError) throw photosError; if (photosError) throw photosError;
setTotalPhotos(photosCount || 0); setTotalPhotos(photosCount || 0);
} catch (error) { } catch (error) {
logger.error('Error fetching statistics', { error }); handleNonCriticalError(error, {
action: 'Fetch manufacturer statistics',
metadata: { manufacturerId }
});
} finally { } finally {
setStatsLoading(false); setStatsLoading(false);
} }

View File

@@ -17,7 +17,7 @@ import { toast } from '@/hooks/use-toast';
import { useAuthModal } from '@/hooks/useAuthModal'; import { useAuthModal } from '@/hooks/useAuthModal';
import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useDocumentTitle } from '@/hooks/useDocumentTitle';
import { useOpenGraph } from '@/hooks/useOpenGraph'; import { useOpenGraph } from '@/hooks/useOpenGraph';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
interface RideModelWithCount extends RideModel { interface RideModelWithCount extends RideModel {
ride_count: number; ride_count: number;
@@ -86,7 +86,10 @@ export default function ManufacturerModels() {
setModels(modelsWithCounts); setModels(modelsWithCounts);
} }
} catch (error) { } catch (error) {
logger.error('Error fetching data', { error }); handleNonCriticalError(error, {
action: 'Fetch manufacturer models',
metadata: { manufacturerSlug }
});
} finally { } finally {
setLoading(false); setLoading(false);
} }

View File

@@ -17,7 +17,7 @@ import { toast } from '@/hooks/use-toast';
import { useAuthModal } from '@/hooks/useAuthModal'; import { useAuthModal } from '@/hooks/useAuthModal';
import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useDocumentTitle } from '@/hooks/useDocumentTitle';
import { useOpenGraph } from '@/hooks/useOpenGraph'; import { useOpenGraph } from '@/hooks/useOpenGraph';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
export default function ManufacturerRides() { export default function ManufacturerRides() {
const { manufacturerSlug } = useParams<{ manufacturerSlug: string }>(); const { manufacturerSlug } = useParams<{ manufacturerSlug: string }>();
@@ -91,7 +91,10 @@ export default function ManufacturerRides() {
setRides((ridesData || []) as any); setRides((ridesData || []) as any);
} }
} catch (error) { } catch (error) {
logger.error('Error fetching data', { error }); handleNonCriticalError(error, {
action: 'Fetch manufacturer rides',
metadata: { manufacturerSlug }
});
} finally { } finally {
setLoading(false); setLoading(false);
} }

View File

@@ -18,7 +18,7 @@ import { ManufacturerCard } from '@/components/manufacturers/ManufacturerCard';
import { ManufacturerListView } from '@/components/manufacturers/ManufacturerListView'; import { ManufacturerListView } from '@/components/manufacturers/ManufacturerListView';
import { ManufacturerForm } from '@/components/admin/ManufacturerForm'; import { ManufacturerForm } from '@/components/admin/ManufacturerForm';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
import { useUserRole } from '@/hooks/useUserRole'; import { useUserRole } from '@/hooks/useUserRole';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
import { submitCompanyCreation } from '@/lib/companyHelpers'; import { submitCompanyCreation } from '@/lib/companyHelpers';
@@ -76,7 +76,10 @@ export default function Manufacturers() {
const { data } = await query; const { data } = await query;
setCompanies(data || []); setCompanies(data || []);
} catch (error) { } catch (error) {
logger.error('Error fetching companies', { error }); handleNonCriticalError(error, {
action: 'Fetch manufacturers',
metadata: { page: 'manufacturers' }
});
} finally { } finally {
setLoading(false); setLoading(false);
} }

View File

@@ -14,7 +14,7 @@ import { Company, Park } from '@/types/database';
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import { OperatorPhotoGallery } from '@/components/companies/OperatorPhotoGallery'; import { OperatorPhotoGallery } from '@/components/companies/OperatorPhotoGallery';
import { ParkCard } from '@/components/parks/ParkCard'; import { ParkCard } from '@/components/parks/ParkCard';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
// Lazy load admin form // Lazy load admin form
const OperatorForm = lazy(() => import('@/components/admin/OperatorForm').then(m => ({ default: m.OperatorForm }))); const OperatorForm = lazy(() => import('@/components/admin/OperatorForm').then(m => ({ default: m.OperatorForm })));

View File

@@ -17,7 +17,7 @@ import { Grid3X3, List } from 'lucide-react';
import { FilterState, SortState } from './Parks'; import { FilterState, SortState } from './Parks';
import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useDocumentTitle } from '@/hooks/useDocumentTitle';
import { useOpenGraph } from '@/hooks/useOpenGraph'; import { useOpenGraph } from '@/hooks/useOpenGraph';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
const initialFilters: FilterState = { const initialFilters: FilterState = {
search: '', search: '',

View File

@@ -17,7 +17,7 @@ import { Grid3X3, List } from 'lucide-react';
import { FilterState, SortState } from './Parks'; import { FilterState, SortState } from './Parks';
import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useDocumentTitle } from '@/hooks/useDocumentTitle';
import { useOpenGraph } from '@/hooks/useOpenGraph'; import { useOpenGraph } from '@/hooks/useOpenGraph';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
const initialFilters: FilterState = { const initialFilters: FilterState = {
search: '', search: '',

View File

@@ -14,8 +14,7 @@ import { RideSubmissionData } from '@/types/submission-data';
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler'; import { getErrorMessage, handleNonCriticalError } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';
import { useAuthModal } from '@/hooks/useAuthModal'; import { useAuthModal } from '@/hooks/useAuthModal';
import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useDocumentTitle } from '@/hooks/useDocumentTitle';
import { useOpenGraph } from '@/hooks/useOpenGraph'; import { useOpenGraph } from '@/hooks/useOpenGraph';

View File

@@ -23,8 +23,7 @@ import { User, MapPin, Calendar, Star, Trophy, Settings, Camera, Edit3, Save, X,
import { Profile as ProfileType } from '@/types/database'; import { Profile as ProfileType } from '@/types/database';
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import { useToast } from '@/hooks/use-toast'; import { useToast } from '@/hooks/use-toast';
import { logger } from '@/lib/logger'; import { getErrorMessage, handleNonCriticalError } from '@/lib/errorHandler';
import { getErrorMessage } from '@/lib/errorHandler';
import { PhotoUpload } from '@/components/upload/PhotoUpload'; import { PhotoUpload } from '@/components/upload/PhotoUpload';
import { profileEditSchema } from '@/lib/validation'; import { profileEditSchema } from '@/lib/validation';
import { LocationDisplay } from '@/components/profile/LocationDisplay'; import { LocationDisplay } from '@/components/profile/LocationDisplay';

View File

@@ -14,7 +14,7 @@ import { Company, Park } from '@/types/database';
import { supabase } from '@/lib/supabaseClient'; import { supabase } from '@/lib/supabaseClient';
import { PropertyOwnerPhotoGallery } from '@/components/companies/PropertyOwnerPhotoGallery'; import { PropertyOwnerPhotoGallery } from '@/components/companies/PropertyOwnerPhotoGallery';
import { ParkCard } from '@/components/parks/ParkCard'; import { ParkCard } from '@/components/parks/ParkCard';
import { logger } from '@/lib/logger'; import { handleNonCriticalError } from '@/lib/errorHandler';
// Lazy load admin form // Lazy load admin form
const PropertyOwnerForm = lazy(() => import('@/components/admin/PropertyOwnerForm').then(m => ({ default: m.PropertyOwnerForm }))); const PropertyOwnerForm = lazy(() => import('@/components/admin/PropertyOwnerForm').then(m => ({ default: m.PropertyOwnerForm })));

View File

@@ -15,8 +15,7 @@ import { getCloudflareImageUrl } from '@/lib/cloudflareImageUtils';
import { useAuthModal } from '@/hooks/useAuthModal'; import { useAuthModal } from '@/hooks/useAuthModal';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler'; import { getErrorMessage, handleNonCriticalError } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';
import { ManufacturerPhotoGallery } from '@/components/companies/ManufacturerPhotoGallery'; import { ManufacturerPhotoGallery } from '@/components/companies/ManufacturerPhotoGallery';
// Lazy load admin form // Lazy load admin form

View File

@@ -14,8 +14,7 @@ import { RideForm } from '@/components/admin/RideForm';
import { useAuth } from '@/hooks/useAuth'; import { useAuth } from '@/hooks/useAuth';
import { useAuthModal } from '@/hooks/useAuthModal'; import { useAuthModal } from '@/hooks/useAuthModal';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
import { getErrorMessage } from '@/lib/errorHandler'; import { getErrorMessage, handleNonCriticalError } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';
import type { Ride, Company, RideModel } from "@/types/database"; import type { Ride, Company, RideModel } from "@/types/database";
import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useDocumentTitle } from '@/hooks/useDocumentTitle';

View File

@@ -75,8 +75,7 @@ import { DialogFooter } from '@/components/ui/dialog';
import { useTheme } from '@/components/theme/ThemeProvider'; import { useTheme } from '@/components/theme/ThemeProvider';
import { useUserRole } from '@/hooks/useUserRole'; import { useUserRole } from '@/hooks/useUserRole';
import { useDocumentTitle } from '@/hooks/useDocumentTitle'; import { useDocumentTitle } from '@/hooks/useDocumentTitle';
import { handleError, handleSuccess } from '@/lib/errorHandler'; import { handleError, handleSuccess, handleNonCriticalError } from '@/lib/errorHandler';
import { logger } from '@/lib/logger';
import { contactCategories } from '@/lib/contactValidation'; import { contactCategories } from '@/lib/contactValidation';
import { invokeWithTracking } from '@/lib/edgeFunctionTracking'; import { invokeWithTracking } from '@/lib/edgeFunctionTracking';
import { AdminLayout } from '@/components/layout/AdminLayout'; import { AdminLayout } from '@/components/layout/AdminLayout';
@@ -199,7 +198,10 @@ export default function AdminContact() {
const { data, error } = await query; const { data, error } = await query;
if (error) { if (error) {
logger.error('Failed to fetch contact submissions', { error: error.message }); handleNonCriticalError(error, {
action: 'Fetch contact submissions',
metadata: { error: error.message }
});
throw error; throw error;
} }
@@ -219,7 +221,10 @@ export default function AdminContact() {
.order('created_at', { ascending: true }) .order('created_at', { ascending: true })
.then(({ data, error }) => { .then(({ data, error }) => {
if (error) { if (error) {
logger.error('Failed to fetch email threads', { error }); handleNonCriticalError(error, {
action: 'Fetch email threads',
metadata: { submissionId: selectedSubmission.id }
});
setEmailThreads([]); setEmailThreads([]);
} else { } else {
setEmailThreads((data as EmailThread[]) || []); setEmailThreads((data as EmailThread[]) || []);
@@ -263,7 +268,10 @@ export default function AdminContact() {
.eq('id', submissionId); .eq('id', submissionId);
if (statusError) { if (statusError) {
logger.error('Failed to update status', { error: statusError }); handleError(statusError, {
action: 'Update contact status',
metadata: { submissionId, newStatus }
});
throw statusError; throw statusError;
} }
} }
@@ -465,8 +473,10 @@ export default function AdminContact() {
.order('created_at', { ascending: true }) .order('created_at', { ascending: true })
.then(({ data, error }) => { .then(({ data, error }) => {
if (error) { if (error) {
logger.error('Failed to refresh email threads', { error }); handleError(error, {
handleError(error, { action: 'Refresh Email Threads' }); action: 'Refresh Email Threads',
metadata: { submissionId: selectedSubmission.id }
});
} else { } else {
setEmailThreads((data as EmailThread[]) || []); setEmailThreads((data as EmailThread[]) || []);
handleSuccess('Refreshed', 'Email thread updated'); handleSuccess('Refreshed', 'Email thread updated');