Improve error handling and navigation safety across the application

Add robust error handling for image uploads, improve navigation logic in AutocompleteSearch with toast notifications for missing identifiers, refine useIsMobile hook return type, and update Supabase function error reporting to handle non-Error types.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: a759d451-40bf-440d-96f5-a19ad6af18a8
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
This commit is contained in:
pac7
2025-10-07 15:25:37 +00:00
parent 8c2ec57f9f
commit 6737431379
11 changed files with 210 additions and 47 deletions

View File

@@ -6,6 +6,7 @@ import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import { useSearch, SearchResult } from '@/hooks/useSearch';
import { useNavigate } from 'react-router-dom';
import { useToast } from '@/components/ui/use-toast';
interface AutocompleteSearchProps {
onResultSelect?: (result: SearchResult) => void;
@@ -29,6 +30,7 @@ export function AutocompleteSearch({
variant = 'default'
}: AutocompleteSearchProps) {
const navigate = useNavigate();
const { toast } = useToast();
const searchRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
const [isOpen, setIsOpen] = useState(false);
@@ -117,23 +119,44 @@ export function AutocompleteSearch({
if (onResultSelect) {
onResultSelect(searchResult);
} else {
// Default navigation
// Default navigation with null/undefined safety checks
switch (searchResult.type) {
case 'park':
navigate(`/parks/${searchResult.slug || searchResult.id}`);
const parkIdentifier = searchResult.slug || searchResult.id;
if (parkIdentifier) {
navigate(`/parks/${parkIdentifier}`);
} else {
toast({
title: "Navigation Error",
description: "Unable to navigate to this park. Missing park identifier.",
variant: "destructive",
});
navigate(`/search?q=${encodeURIComponent(searchResult.title)}`);
}
break;
case 'ride':
const parkSlug = (searchResult.data as any).park?.slug;
const parkSlug = (searchResult.data as any)?.park?.slug;
const rideSlug = searchResult.slug;
const rideId = searchResult.id;
if (parkSlug && rideSlug) {
navigate(`/parks/${parkSlug}/rides/${rideSlug}`);
} else if (rideId) {
navigate(`/rides/${rideId}`);
} else {
navigate(`/rides/${searchResult.id}`);
toast({
title: "Navigation Error",
description: "Unable to navigate to this ride. Missing ride identifier.",
variant: "destructive",
});
navigate(`/search?q=${encodeURIComponent(searchResult.title)}`);
}
break;
case 'company':
const companyType = (searchResult.data as any).company_type;
const companyType = (searchResult.data as any)?.company_type;
const companySlug = searchResult.slug;
const companyId = searchResult.id;
if (companyType && companySlug) {
switch (companyType) {
case 'operator':
@@ -149,10 +172,26 @@ export function AutocompleteSearch({
navigate(`/designers/${companySlug}`);
break;
default:
navigate(`/companies/${searchResult.id}`);
if (companyId) {
navigate(`/companies/${companyId}`);
} else {
toast({
title: "Navigation Error",
description: "Unable to navigate to this company. Missing company identifier.",
variant: "destructive",
});
navigate(`/search?q=${encodeURIComponent(searchResult.title)}`);
}
}
} else if (companyId) {
navigate(`/companies/${companyId}`);
} else {
navigate(`/companies/${searchResult.id}`);
toast({
title: "Navigation Error",
description: "Unable to navigate to this company. Missing company identifier.",
variant: "destructive",
});
navigate(`/search?q=${encodeURIComponent(searchResult.title)}`);
}
break;
}