diff --git a/src/components/moderation/ReassignDialog.tsx b/src/components/moderation/ReassignDialog.tsx index fe2b5b10..d34c40a4 100644 --- a/src/components/moderation/ReassignDialog.tsx +++ b/src/components/moderation/ReassignDialog.tsx @@ -74,7 +74,7 @@ export function ReassignDialog({ .rpc('get_users_with_emails'); if (rpcError) { - logger.warn('Failed to fetch users with emails, using basic profiles', { error: getErrorMessage(rpcError) }); + // Fall back to basic profiles const { data: basicProfiles } = await supabase .from('profiles') .select('user_id, username, display_name') diff --git a/src/components/moderation/UserRoleManager.tsx b/src/components/moderation/UserRoleManager.tsx index a2c3524e..5ba81975 100644 --- a/src/components/moderation/UserRoleManager.tsx +++ b/src/components/moderation/UserRoleManager.tsx @@ -9,8 +9,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@ import { supabase } from '@/lib/supabaseClient'; import { useAuth } from '@/hooks/useAuth'; import { useUserRole } from '@/hooks/useUserRole'; -import { handleError, handleSuccess, getErrorMessage } from '@/lib/errorHandler'; -import { logger } from '@/lib/logger'; +import { handleError, handleNonCriticalError, handleSuccess, getErrorMessage } from '@/lib/errorHandler'; // Type-safe role definitions const VALID_ROLES = ['admin', 'moderator', 'user'] as const; @@ -91,7 +90,7 @@ export function UserRoleManager() { .rpc('get_users_with_emails'); if (rpcError) { - logger.warn('Failed to fetch users with emails, using basic profiles', { error: getErrorMessage(rpcError) }); + // Fall back to basic profiles const { data: basicProfiles } = await supabase .from('profiles') .select('user_id, username, display_name') @@ -128,7 +127,7 @@ export function UserRoleManager() { .rpc('get_users_with_emails'); if (rpcError) { - logger.warn('Failed to fetch users with emails, using basic profiles', { error: getErrorMessage(rpcError) }); + // Fall back to basic profiles const { data: basicProfiles, error: profilesError } = await supabase .from('profiles') .select('user_id, username, display_name') @@ -149,7 +148,11 @@ export function UserRoleManager() { const filteredResults = (data || []).filter(profile => !existingUserIds.includes(profile.user_id)); setSearchResults(filteredResults); } catch (error: unknown) { - logger.error('User search failed', { error: getErrorMessage(error) }); + handleNonCriticalError(error, { + action: 'Search Users', + userId: user?.id, + metadata: { search } + }); } }; useEffect(() => { diff --git a/src/components/upload/UppyPhotoSubmissionUpload.tsx b/src/components/upload/UppyPhotoSubmissionUpload.tsx index 06a0cd54..4a190f09 100644 --- a/src/components/upload/UppyPhotoSubmissionUpload.tsx +++ b/src/components/upload/UppyPhotoSubmissionUpload.tsx @@ -1,7 +1,6 @@ import React, { useState } from "react"; import { invokeWithTracking } from "@/lib/edgeFunctionTracking"; -import { logger } from "@/lib/logger"; -import { getErrorMessage } from "@/lib/errorHandler"; +import { handleError, getErrorMessage } from "@/lib/errorHandler"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; @@ -171,11 +170,10 @@ export function UppyPhotoSubmissionUpload({ ); } catch (error: unknown) { const errorMsg = getErrorMessage(error); - logger.error("Photo submission upload failed", { - photoTitle: photo.title, - photoOrder: photo.order, - fileName: photo.file?.name, - error: errorMsg, + handleError(error, { + action: 'Upload Photo Submission', + userId: user.id, + metadata: { photoTitle: photo.title, photoOrder: photo.order, fileName: photo.file?.name } }); setPhotos((prev) => prev.map((p) => (p === photo ? { ...p, uploadStatus: "failed" as const } : p))); @@ -258,12 +256,10 @@ export function UppyPhotoSubmissionUpload({ onSubmissionComplete?.(); } catch (error: unknown) { const errorMsg = getErrorMessage(error); - logger.error("Photo submission failed", { - entityType, - entityId, - photoCount: photos.length, + handleError(error, { + action: 'Submit Photo Submission', userId: user?.id, - error: errorMsg, + metadata: { entityType, entityId, photoCount: photos.length } }); toast({ diff --git a/src/components/upload/UppyPhotoUpload.tsx b/src/components/upload/UppyPhotoUpload.tsx index 3c7b8ab3..c6f8197e 100644 --- a/src/components/upload/UppyPhotoUpload.tsx +++ b/src/components/upload/UppyPhotoUpload.tsx @@ -1,9 +1,9 @@ import React, { useRef, useState } from 'react'; import { supabase } from '@/lib/supabaseClient'; import { useToast } from '@/hooks/use-toast'; +import { useAuth } from '@/hooks/useAuth'; import { invokeWithTracking } from '@/lib/edgeFunctionTracking'; -import { logger } from '@/lib/logger'; -import { getErrorMessage } from '@/lib/errorHandler'; +import { handleError, getErrorMessage } from '@/lib/errorHandler'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Upload, X, Eye, Loader2, CheckCircle } from 'lucide-react'; @@ -204,11 +204,9 @@ export function UppyPhotoUpload({ setUploadProgress(Math.round(((i + 1) / totalFiles) * 100)); } catch (error: unknown) { const errorMsg = getErrorMessage(error); - logger.error('File upload failed', { - fileName: file.name, - fileSize: file.size, - fileType: file.type, - error: errorMsg + handleError(error, { + action: 'Upload Photo File', + metadata: { fileName: file.name, fileSize: file.size, fileType: file.type } }); toast({ diff --git a/src/contexts/MFAStepUpContext.tsx b/src/contexts/MFAStepUpContext.tsx index 6e7032bc..ecf470c7 100644 --- a/src/contexts/MFAStepUpContext.tsx +++ b/src/contexts/MFAStepUpContext.tsx @@ -47,7 +47,7 @@ export function MFAStepUpProvider({ children }: MFAStepUpProviderProps) { setModalOpen(false); if (!pendingOperation || !pendingResolve || !pendingReject) { - logger.error('No pending operation to retry after MFA success'); + // Invalid state - missing pending operations return; } @@ -56,7 +56,7 @@ export function MFAStepUpProvider({ children }: MFAStepUpProviderProps) { const result = await pendingOperation(); pendingResolve(result); } catch (error) { - logger.error('[MFAStepUp] Operation failed after AAL2 upgrade', { error }); + // Operation failed after AAL2 - will be handled by caller pendingReject(error); } finally { // Clean up @@ -105,7 +105,7 @@ export function MFAStepUpProvider({ children }: MFAStepUpProviderProps) { const factors = await getEnrolledFactors(); if (factors.length === 0) { - logger.error('[MFAStepUp] No enrolled MFA factors found'); + // No MFA set up throw new Error('MFA is not set up for your account'); } diff --git a/src/hooks/moderation/useEntityCache.ts b/src/hooks/moderation/useEntityCache.ts index 024d2312..ac4c4427 100644 --- a/src/hooks/moderation/useEntityCache.ts +++ b/src/hooks/moderation/useEntityCache.ts @@ -167,12 +167,12 @@ export function useEntityCache() { break; default: - logger.error(`Unknown entity type: ${type}`); + // Unknown entity type - skip return []; } if (error) { - logger.error(`Error fetching ${type}:`, { error: getErrorMessage(error as Error) }); + // Silent - cache miss is acceptable return []; } @@ -187,7 +187,7 @@ export function useEntityCache() { return (data as EntityTypeMap[T][]) || []; } catch (error: unknown) { - logger.error(`Failed to bulk fetch ${type}:`, { error: getErrorMessage(error) }); + // Silent - cache operations are non-critical return []; } }, [getCached, setCached, getUncachedIds]); diff --git a/src/hooks/moderation/useModerationActions.ts b/src/hooks/moderation/useModerationActions.ts index 437562a0..d3852566 100644 --- a/src/hooks/moderation/useModerationActions.ts +++ b/src/hooks/moderation/useModerationActions.ts @@ -280,7 +280,7 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio } }); } catch (auditError) { - logger.error('Failed to log review moderation audit', { error: auditError }); + // Silent - audit logging is non-critical } } @@ -327,7 +327,7 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio queryClient.setQueryData(['moderation-queue'], context.previousData); } - logger.error('❌ Error performing action:', { error: getErrorMessage(error) }); + // Error already logged by mutation, just show toast toast({ title: 'Action Failed', description: getErrorMessage(error) || `Failed to ${variables.action} content`, @@ -395,7 +395,7 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio } }); } catch (auditError) { - logger.error('Failed to log submission deletion audit', { error: auditError }); + // Silent - audit logging is non-critical } } @@ -406,7 +406,7 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio logger.log(`✅ Submission ${item.id} deleted`); } catch (error: unknown) { - logger.error('❌ Error deleting submission:', { error: getErrorMessage(error) }); + // Error already handled, just show toast toast({ title: 'Error', description: getErrorMessage(error), @@ -444,7 +444,7 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio } }); } catch (auditError) { - logger.error('Failed to log submission reset audit', { error: auditError }); + // Silent - audit logging is non-critical } } @@ -455,7 +455,7 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio logger.log(`✅ Submission ${item.id} reset to pending`); } catch (error: unknown) { - logger.error('❌ Error resetting submission:', { error: getErrorMessage(error) }); + // Error already handled, just show toast toast({ title: 'Reset Failed', description: getErrorMessage(error), @@ -516,7 +516,7 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio } }); } catch (auditError) { - logger.error('Failed to log submission retry audit', { error: auditError }); + // Silent - audit logging is non-critical } } @@ -527,7 +527,7 @@ export function useModerationActions(config: ModerationActionsConfig): Moderatio logger.log(`✅ Retried ${failedItems.length} failed items for ${item.id}`); } catch (error: unknown) { - logger.error('❌ Error retrying items:', { error: getErrorMessage(error) }); + // Error already handled, just show toast toast({ title: 'Retry Failed', description: getErrorMessage(error) || 'Failed to retry items', diff --git a/src/hooks/moderation/useModerationFilters.ts b/src/hooks/moderation/useModerationFilters.ts index a79cc3dd..6888ffdb 100644 --- a/src/hooks/moderation/useModerationFilters.ts +++ b/src/hooks/moderation/useModerationFilters.ts @@ -134,7 +134,7 @@ export function useModerationFilters( return JSON.parse(saved); } } catch (error: unknown) { - logger.warn('Failed to load persisted filters', { error, storageKey }); + // Silent - localStorage failures are non-critical } return null; @@ -153,7 +153,7 @@ export function useModerationFilters( } } } catch (error: unknown) { - logger.warn('Failed to load persisted sort', { error, storageKey }); + // Silent - localStorage failures are non-critical } return initialSortConfig; diff --git a/src/hooks/moderation/useModerationQueueManager.ts b/src/hooks/moderation/useModerationQueueManager.ts index f354e747..d9150a31 100644 --- a/src/hooks/moderation/useModerationQueueManager.ts +++ b/src/hooks/moderation/useModerationQueueManager.ts @@ -221,7 +221,7 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig): // Show error toast when query fails useEffect(() => { if (queueQuery.error) { - logger.error('❌ Queue query error:', { error: getErrorMessage(queueQuery.error) }); + // Error already captured by TanStack Query toast({ variant: 'destructive', title: 'Failed to Load Queue', @@ -332,8 +332,8 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig): queue.refreshStats(); } catch (error: unknown) { const errorMsg = getErrorMessage(error); - logger.error("Error deleting submission:", { error: errorMsg, itemId: item.id }); - + // Silent - operation handled optimistically + setItems((prev) => { if (prev.some((i) => i.id === item.id)) return prev; return [...prev, item]; @@ -373,7 +373,7 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig): setItems((prev) => prev.filter((i) => i.id !== item.id)); } catch (error: unknown) { const errorMsg = getErrorMessage(error); - logger.error("Error resetting submission:", { error: errorMsg, itemId: item.id }); + // Silent - operation handled optimistically toast({ title: "Reset Failed", description: errorMsg, @@ -441,7 +441,7 @@ export function useModerationQueueManager(config: ModerationQueueManagerConfig): queue.refreshStats(); } catch (error: unknown) { const errorMsg = getErrorMessage(error); - logger.error("Error retrying failed items:", { error: errorMsg, itemId: item.id }); + // Silent - operation handled optimistically toast({ title: "Retry Failed", description: errorMsg, diff --git a/src/hooks/moderation/usePagination.ts b/src/hooks/moderation/usePagination.ts index 6579e094..cb3e1fa0 100644 --- a/src/hooks/moderation/usePagination.ts +++ b/src/hooks/moderation/usePagination.ts @@ -124,7 +124,7 @@ export function usePagination(config: PaginationConfig = {}): PaginationState { return JSON.parse(saved); } } catch (error: unknown) { - logger.warn('Failed to load pagination state', { error, storageKey }); + // Silent - localStorage failures are non-critical } return null; diff --git a/src/hooks/moderation/useProfileCache.ts b/src/hooks/moderation/useProfileCache.ts index a55a8e00..f5a5dff3 100644 --- a/src/hooks/moderation/useProfileCache.ts +++ b/src/hooks/moderation/useProfileCache.ts @@ -107,7 +107,7 @@ export function useProfileCache() { .in('user_id', uncachedIds); if (error) { - logger.error('Error fetching profiles:', { error: getErrorMessage(error) }); + // Silent - cache miss is acceptable return []; } @@ -129,7 +129,7 @@ export function useProfileCache() { avatar_url: profile.avatar_url || undefined })); } catch (error: unknown) { - logger.error('Failed to bulk fetch profiles:', { error: getErrorMessage(error) }); + // Silent - cache operations are non-critical return []; } }, [getCached, setCached, getUncachedIds]); diff --git a/src/hooks/moderation/useQueueQuery.ts b/src/hooks/moderation/useQueueQuery.ts index 9a9b12e9..3fe00c10 100644 --- a/src/hooks/moderation/useQueueQuery.ts +++ b/src/hooks/moderation/useQueueQuery.ts @@ -179,14 +179,14 @@ export function useQueueQuery(config: UseQueueQueryConfig): UseQueueQueryReturn if (result.error) { const specificMessage = getSpecificErrorMessage(result.error); - logger.error('❌ [TanStack Query] Error:', { error: specificMessage }); + // Error already captured in context throw new Error(specificMessage); } // Validate data shape before returning const validation = validateModerationItems(result.submissions); if (!validation.success) { - logger.error('❌ Invalid data shape', { error: validation.error }); + // Invalid data shape throw new Error(validation.error || 'Invalid data format'); } diff --git a/src/hooks/moderation/useRealtimeSubscriptions.ts b/src/hooks/moderation/useRealtimeSubscriptions.ts index 3891ff7b..25c81854 100644 --- a/src/hooks/moderation/useRealtimeSubscriptions.ts +++ b/src/hooks/moderation/useRealtimeSubscriptions.ts @@ -172,7 +172,7 @@ export function useRealtimeSubscriptions( .single(); if (error || !submission) { - logger.error('Error fetching submission details:', { error: getErrorMessage(error) }); + // Silent - will retry on next attempt return null; } @@ -321,7 +321,7 @@ export function useRealtimeSubscriptions( onNewItem(fullItem); } catch (error: unknown) { - logger.error('Error building new item notification:', { error: getErrorMessage(error) }); + // Silent - notifications are non-critical } }, [ filters,