diff --git a/src/components/upload/UppyPhotoSubmissionUpload.tsx b/src/components/upload/UppyPhotoSubmissionUpload.tsx index f7b263e3..4f6d337b 100644 --- a/src/components/upload/UppyPhotoSubmissionUpload.tsx +++ b/src/components/upload/UppyPhotoSubmissionUpload.tsx @@ -1,5 +1,7 @@ import React, { useState } from 'react'; import { invokeWithTracking } from '@/lib/edgeFunctionTracking'; +import { logger } from '@/lib/logger'; +import { 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'; @@ -168,11 +170,19 @@ export function UppyPhotoSubmissionUpload({ )); } catch (error: unknown) { - console.error('Upload error:', error); + const errorMsg = getErrorMessage(error); + logger.error('Photo submission upload failed', { + photoTitle: photo.title, + photoOrder: photo.order, + fileName: photo.file?.name, + error: errorMsg + }); + setPhotos(prev => prev.map(p => p === photo ? { ...p, uploadStatus: 'failed' as const } : p )); - throw new Error(`Failed to upload ${photo.title || 'photo'}: ${error instanceof Error ? error.message : 'Unknown error'}`); + + throw new Error(`Failed to upload ${photo.title || 'photo'}: ${errorMsg}`); } } } @@ -248,11 +258,19 @@ export function UppyPhotoSubmissionUpload({ setPhotos([]); onSubmissionComplete?.(); } catch (error: unknown) { - console.error('Submission error:', error); + const errorMsg = getErrorMessage(error); + logger.error('Photo submission failed', { + entityType, + entityId, + photoCount: photos.length, + userId: user?.id, + error: errorMsg + }); + toast({ variant: 'destructive', title: 'Submission Failed', - description: error instanceof Error ? error.message : 'There was an error submitting your photos. Please try again.', + description: errorMsg || 'There was an error submitting your photos. Please try again.', }); } finally { setIsSubmitting(false); diff --git a/src/components/upload/UppyPhotoUpload.tsx b/src/components/upload/UppyPhotoUpload.tsx index d5475c38..231606d3 100644 --- a/src/components/upload/UppyPhotoUpload.tsx +++ b/src/components/upload/UppyPhotoUpload.tsx @@ -2,6 +2,8 @@ import React, { useRef, useState } from 'react'; import { supabase } from '@/integrations/supabase/client'; import { useToast } from '@/hooks/use-toast'; import { invokeWithTracking } from '@/lib/edgeFunctionTracking'; +import { logger } from '@/lib/logger'; +import { 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'; @@ -201,11 +203,18 @@ export function UppyPhotoUpload({ newUrls.push(url); setUploadProgress(Math.round(((i + 1) / totalFiles) * 100)); } catch (error: unknown) { - console.error(`Upload failed for ${file.name}:`, error); + const errorMsg = getErrorMessage(error); + logger.error('File upload failed', { + fileName: file.name, + fileSize: file.size, + fileType: file.type, + error: errorMsg + }); + toast({ variant: 'destructive', title: 'Upload Failed', - description: `Failed to upload "${file.name}": ${error instanceof Error ? error.message : 'Unknown error'}`, + description: `Failed to upload "${file.name}": ${errorMsg}`, }); onUploadError?.(error as Error); } diff --git a/src/hooks/useAutocompleteData.ts b/src/hooks/useAutocompleteData.ts index 17e17ab9..5ac0adad 100644 --- a/src/hooks/useAutocompleteData.ts +++ b/src/hooks/useAutocompleteData.ts @@ -1,6 +1,9 @@ import { useState, useEffect } from 'react'; import { supabase } from '@/integrations/supabase/client'; import { ComboboxOption } from '@/components/ui/combobox'; +import { toast } from 'sonner'; +import { logger } from '@/lib/logger'; +import { getErrorMessage } from '@/lib/errorHandler'; export function useCountries() { const [countries, setCountries] = useState([]); @@ -28,7 +31,11 @@ export function useCountries() { })) ); } catch (error: unknown) { - console.error('Error fetching countries:', error); + const errorMsg = getErrorMessage(error); + logger.error('Failed to fetch countries', { error: errorMsg }); + toast.error('Failed to load countries', { + description: 'Please refresh the page and try again.', + }); setCountries([]); } finally { setLoading(false); @@ -73,7 +80,11 @@ export function useStatesProvinces(country?: string) { })) ); } catch (error: unknown) { - console.error('Error fetching states/provinces:', error); + const errorMsg = getErrorMessage(error); + logger.error('Failed to fetch states/provinces', { country, error: errorMsg }); + toast.error('Failed to load states/provinces', { + description: 'Please refresh the page and try again.', + }); setStatesProvinces([]); } finally { setLoading(false); @@ -109,7 +120,11 @@ export function useManufacturers() { })) ); } catch (error: unknown) { - console.error('Error fetching manufacturers:', error); + const errorMsg = getErrorMessage(error); + logger.error('Failed to fetch manufacturers', { error: errorMsg }); + toast.error('Failed to load manufacturers', { + description: 'Please refresh the page and try again.', + }); setManufacturers([]); } finally { setLoading(false); @@ -150,7 +165,11 @@ export function useRideModels(manufacturerId?: string) { })) ); } catch (error: unknown) { - console.error('Error fetching ride models:', error); + const errorMsg = getErrorMessage(error); + logger.error('Failed to fetch ride models', { manufacturerId, error: errorMsg }); + toast.error('Failed to load ride models', { + description: 'Please refresh the page and try again.', + }); setRideModels([]); } finally { setLoading(false); @@ -189,7 +208,11 @@ export function useCompanyHeadquarters() { })) ); } catch (error: unknown) { - console.error('Error fetching headquarters:', error); + const errorMsg = getErrorMessage(error); + logger.error('Failed to fetch headquarters', { error: errorMsg }); + toast.error('Failed to load headquarters', { + description: 'Please refresh the page and try again.', + }); setHeadquarters([]); } finally { setLoading(false); @@ -225,7 +248,11 @@ export function useOperators() { })) ); } catch (error: unknown) { - console.error('Error fetching operators:', error); + const errorMsg = getErrorMessage(error); + logger.error('Failed to fetch operators', { error: errorMsg }); + toast.error('Failed to load operators', { + description: 'Please refresh the page and try again.', + }); setOperators([]); } finally { setLoading(false); @@ -261,7 +288,11 @@ export function usePropertyOwners() { })) ); } catch (error: unknown) { - console.error('Error fetching property owners:', error); + const errorMsg = getErrorMessage(error); + logger.error('Failed to fetch property owners', { error: errorMsg }); + toast.error('Failed to load property owners', { + description: 'Please refresh the page and try again.', + }); setPropertyOwners([]); } finally { setLoading(false); diff --git a/src/hooks/useEntityVersions.ts b/src/hooks/useEntityVersions.ts index 147bf07a..1dada667 100644 --- a/src/hooks/useEntityVersions.ts +++ b/src/hooks/useEntityVersions.ts @@ -109,7 +109,7 @@ export function useEntityVersions(entityType: EntityType, entityId: string) { } } catch (error: unknown) { const errorMsg = getErrorMessage(error); - console.error('Error fetching versions:', errorMsg); + logger.error('Failed to fetch versions', { entityType, entityId, error: errorMsg }); if (isMountedRef.current && currentRequestId === requestCounterRef.current) { toast.error(errorMsg); @@ -141,7 +141,7 @@ export function useEntityVersions(entityType: EntityType, entityId: string) { return data; } catch (error: unknown) { const errorMsg = getErrorMessage(error); - console.error('Error comparing versions:', errorMsg); + logger.error('Failed to compare versions', { entityType, fromVersionId, toVersionId, error: errorMsg }); if (isMountedRef.current) { toast.error(errorMsg); } @@ -173,7 +173,7 @@ export function useEntityVersions(entityType: EntityType, entityId: string) { return data; } catch (error: unknown) { const errorMsg = getErrorMessage(error); - console.error('Error rolling back version:', errorMsg); + logger.error('Failed to rollback version', { entityType, entityId, targetVersionId, error: errorMsg }); if (isMountedRef.current) { toast.error(errorMsg); } @@ -194,6 +194,7 @@ export function useEntityVersions(entityType: EntityType, entityId: string) { try { supabase.removeChannel(channelRef.current); } catch (error: unknown) { + logger.error('Failed to cleanup realtime subscription', { entityType, entityId, error: getErrorMessage(error) }); console.error('Error removing previous channel:', error); } finally { channelRef.current = null; @@ -226,6 +227,7 @@ export function useEntityVersions(entityType: EntityType, entityId: string) { return () => { if (channelRef.current) { supabase.removeChannel(channelRef.current).catch((error) => { + logger.error('Failed to cleanup realtime subscription', { entityType, entityId, error: getErrorMessage(error) }); console.error('Error removing channel:', error); }); channelRef.current = null; diff --git a/src/hooks/useSearch.tsx b/src/hooks/useSearch.tsx index d0193035..9bb629ba 100644 --- a/src/hooks/useSearch.tsx +++ b/src/hooks/useSearch.tsx @@ -3,6 +3,8 @@ import { supabase } from '@/integrations/supabase/client'; import { Park, Ride, Company } from '@/types/database'; import { logger } from '@/lib/logger'; import * as storage from '@/lib/localStorage'; +import { toast } from 'sonner'; +import { getErrorMessage } from '@/lib/errorHandler'; export interface SearchResult { id: string; @@ -165,9 +167,18 @@ export function useSearch(options: UseSearchOptions = {}) { setResults(searchResults.slice(0, limit)); } catch (error: unknown) { - console.error('Search error:', error); - const errorMessage = error instanceof Error ? error.message : 'Failed to search. Please try again.'; - setError(errorMessage); + const errorMsg = getErrorMessage(error); + logger.error('Search failed', { + query: searchQuery, + types, + error: errorMsg + }); + + toast.error('Search failed', { + description: 'Unable to search. Please try again.', + }); + + setError('Failed to search. Please try again.'); setResults([]); } finally { setLoading(false);