diff --git a/src/components/moderation/RecentActivity.tsx b/src/components/moderation/RecentActivity.tsx index 6fbdb160..4892922e 100644 --- a/src/components/moderation/RecentActivity.tsx +++ b/src/components/moderation/RecentActivity.tsx @@ -50,52 +50,122 @@ export const RecentActivity = forwardRef((props, ref) => { } // Fetch recent approved/rejected submissions - const { data: submissions, error: submissionsError } = await supabase - .from('content_submissions') - .select('id, status, reviewed_at, reviewer_id, submission_type') - .in('status', ['approved', 'rejected']) - .not('reviewed_at', 'is', null) - .order('reviewed_at', { ascending: false }) - .limit(15); + let submissions: any[] = []; + try { + const { data, error } = await supabase + .from('content_submissions') + .select('id, status, reviewed_at, reviewer_id, submission_type') + .in('status', ['approved', 'rejected']) + .not('reviewed_at', 'is', null) + .order('reviewed_at', { ascending: false }) + .limit(15); - if (submissionsError) throw submissionsError; + if (error) { + handleError(error, { + action: 'Load Recent Activity - Submissions', + userId: user?.id, + metadata: { silent } + }); + } else { + submissions = data || []; + } + } catch (error) { + handleError(error, { + action: 'Load Recent Activity - Submissions Query', + userId: user?.id, + metadata: { silent } + }); + } // Fetch recent report resolutions - const { data: reports, error: reportsError } = await supabase - .from('reports') - .select('id, status, reviewed_at, reviewed_by, reported_entity_type') - .in('status', ['reviewed', 'dismissed']) - .not('reviewed_at', 'is', null) - .order('reviewed_at', { ascending: false }) - .limit(15); + let reports: any[] = []; + try { + const { data, error } = await supabase + .from('reports') + .select('id, status, reviewed_at, reviewed_by, reported_entity_type') + .in('status', ['reviewed', 'dismissed']) + .not('reviewed_at', 'is', null) + .order('reviewed_at', { ascending: false }) + .limit(15); - if (reportsError) throw reportsError; + if (error) { + handleError(error, { + action: 'Load Recent Activity - Reports', + userId: user?.id, + metadata: { silent } + }); + } else { + reports = data || []; + } + } catch (error) { + handleError(error, { + action: 'Load Recent Activity - Reports Query', + userId: user?.id, + metadata: { silent } + }); + } // Fetch recent review moderations - const { data: reviews, error: reviewsError } = await supabase - .from('reviews') - .select('id, moderation_status, moderated_at, moderated_by, park_id, ride_id') - .in('moderation_status', ['approved', 'rejected', 'flagged']) - .not('moderated_at', 'is', null) - .order('moderated_at', { ascending: false }) - .limit(15); + let reviews: any[] = []; + try { + const { data, error } = await supabase + .from('reviews') + .select('id, moderation_status, moderated_at, moderated_by, park_id, ride_id') + .in('moderation_status', ['approved', 'rejected', 'flagged']) + .not('moderated_at', 'is', null) + .order('moderated_at', { ascending: false }) + .limit(15); - if (reviewsError) throw reviewsError; + if (error) { + handleError(error, { + action: 'Load Recent Activity - Reviews', + userId: user?.id, + metadata: { silent } + }); + } else { + reviews = data || []; + } + } catch (error) { + handleError(error, { + action: 'Load Recent Activity - Reviews Query', + userId: user?.id, + metadata: { silent } + }); + } - // Get unique moderator IDs + // Get unique moderator IDs with safe filtering const moderatorIds: string[] = [ - ...(submissions?.map(s => s.reviewer_id).filter((id): id is string => id != null) || []), - ...(reports?.map(r => r.reviewed_by).filter((id): id is string => id != null) || []), - ...(reviews?.map(r => r.moderated_by).filter((id): id is string => id != null) || []), + ...(submissions.map(s => s.reviewer_id).filter((id): id is string => id != null)), + ...(reports.map(r => r.reviewed_by).filter((id): id is string => id != null)), + ...(reviews.map(r => r.moderated_by).filter((id): id is string => id != null)), ].filter((id, index, arr) => arr.indexOf(id) === index); - // Fetch moderator profiles - const { data: profiles } = await supabase - .from('profiles') - .select('user_id, username, display_name, avatar_url') - .in('user_id', moderatorIds); + // Fetch moderator profiles only if we have IDs + let profileMap = new Map(); + if (moderatorIds.length > 0) { + try { + const { data: profiles, error: profilesError } = await supabase + .from('profiles') + .select('user_id, username, display_name, avatar_url') + .in('user_id', moderatorIds); - const profileMap = new Map(profiles?.map(p => [p.user_id, p]) || []); + if (profilesError) { + handleError(profilesError, { + action: 'Load Recent Activity - Profiles', + userId: user?.id, + metadata: { moderatorIds: moderatorIds.length } + }); + } else if (profiles) { + profileMap = new Map(profiles.map(p => [p.user_id, p])); + } + } catch (error) { + handleError(error, { + action: 'Load Recent Activity - Profiles Query', + userId: user?.id, + metadata: { moderatorIds: moderatorIds.length } + }); + } + } // Combine all activities const allActivities: ActivityItem[] = [ diff --git a/src/lib/errorHandler.ts b/src/lib/errorHandler.ts index 2e98dc63..4ef0909d 100644 --- a/src/lib/errorHandler.ts +++ b/src/lib/errorHandler.ts @@ -35,13 +35,29 @@ export const handleError = ( ? error.message : 'An unexpected error occurred'; - // Log to console/monitoring + // Log to console/monitoring with enhanced debugging + const stack = error instanceof Error ? error.stack : undefined; + logger.error('Error occurred', { ...context, error: error instanceof Error ? error.message : String(error), - stack: error instanceof Error ? error.stack : undefined, + stack, errorId, + errorType: typeof error, + errorConstructor: error?.constructor?.name, + hasStack: !!stack, }); + + // Additional debug logging when stack is missing + if (!stack) { + console.error('[handleError] Error without stack trace:', { + type: typeof error, + constructor: error?.constructor?.name, + error: error, + context, + errorId + }); + } // Log to database with breadcrumbs (non-blocking) try {