feat: Add error boundaries to submission queries

This commit is contained in:
gpt-engineer-app[bot]
2025-11-05 20:05:01 +00:00
parent 5513f532ee
commit 5e4ed810c0
5 changed files with 90 additions and 23 deletions

View File

@@ -0,0 +1,43 @@
import React, { ReactNode } from 'react';
import { AlertCircle } from 'lucide-react';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { ModerationErrorBoundary } from './ModerationErrorBoundary';
interface SubmissionErrorBoundaryProps {
children: ReactNode;
submissionId?: string;
}
/**
* Lightweight Error Boundary for Submission-Related Components
*
* Wraps ModerationErrorBoundary with a submission-specific fallback UI.
* Use this for any component that displays submission data.
*
* Usage:
* ```tsx
* <SubmissionErrorBoundary submissionId={id}>
* <SubmissionDetails />
* </SubmissionErrorBoundary>
* ```
*/
export function SubmissionErrorBoundary({
children,
submissionId
}: SubmissionErrorBoundaryProps) {
return (
<ModerationErrorBoundary
submissionId={submissionId}
fallback={
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertDescription>
Failed to load submission data. Please try refreshing the page.
</AlertDescription>
</Alert>
}
>
{children}
</ModerationErrorBoundary>
);
}

View File

@@ -10,3 +10,4 @@ export { AdminErrorBoundary } from './AdminErrorBoundary';
export { EntityErrorBoundary } from './EntityErrorBoundary';
export { RouteErrorBoundary } from './RouteErrorBoundary';
export { ModerationErrorBoundary } from './ModerationErrorBoundary';
export { SubmissionErrorBoundary } from './SubmissionErrorBoundary';

View File

@@ -4,7 +4,9 @@ import { Card, CardContent } from '@/components/ui/card';
import { supabase } from '@/lib/supabaseClient';
import { Image as ImageIcon } from 'lucide-react';
import { PhotoModal } from './PhotoModal';
import { handleError } from '@/lib/errorHandler';
import { handleError, getErrorMessage } from '@/lib/errorHandler';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { AlertCircle } from 'lucide-react';
interface EntityEditPreviewProps {
submissionId: string;
@@ -68,6 +70,7 @@ interface SubmissionItemData {
export const EntityEditPreview = ({ submissionId, entityType, entityName }: EntityEditPreviewProps) => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [itemData, setItemData] = useState<Record<string, unknown> | null>(null);
const [originalData, setOriginalData] = useState<Record<string, unknown> | null>(null);
const [changedFields, setChangedFields] = useState<string[]>([]);
@@ -196,10 +199,12 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
setChangedFields(changed);
}
} catch (error: unknown) {
const errorMsg = getErrorMessage(error);
handleError(error, {
action: 'Load Submission Preview',
metadata: { submissionId, entityType }
});
setError(errorMsg);
} finally {
setLoading(false);
}
@@ -213,6 +218,17 @@ export const EntityEditPreview = ({ submissionId, entityType, entityName }: Enti
);
}
if (error) {
return (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertDescription>
{error}
</AlertDescription>
</Alert>
);
}
if (!itemData) {
return (
<div className="text-sm text-muted-foreground">

View File

@@ -40,6 +40,7 @@ import { ConflictResolutionModal } from './ConflictResolutionModal';
import { EditHistoryAccordion } from './EditHistoryAccordion';
import { validateMultipleItems, ValidationResult } from '@/lib/entityValidationSchemas';
import { logger } from '@/lib/logger';
import { ModerationErrorBoundary } from '@/components/error';
interface SubmissionReviewManagerProps {
submissionId: string;
@@ -588,6 +589,7 @@ export function SubmissionReviewManager({
return (
<>
<Container open={open} onOpenChange={onOpenChange}>
<ModerationErrorBoundary submissionId={submissionId}>
{isMobile ? (
<SheetContent side="bottom" className="h-[90vh] overflow-y-auto">
<SheetHeader>
@@ -609,6 +611,7 @@ export function SubmissionReviewManager({
<ReviewContent />
</DialogContent>
)}
</ModerationErrorBoundary>
</Container>
<ConflictResolutionDialog

View File

@@ -5,7 +5,7 @@
import { useState, useEffect } from 'react';
import { supabase } from '@/lib/supabaseClient';
import { getErrorMessage } from '@/lib/errorHandler';
import { handleNonCriticalError, getErrorMessage } from '@/lib/errorHandler';
import type { PhotoSubmissionItem } from '@/types/photo-submissions';
interface UsePhotoSubmissionItemsResult {
@@ -64,6 +64,10 @@ export function usePhotoSubmissionItems(
setPhotos(data || []);
} catch (error: unknown) {
const errorMsg = getErrorMessage(error);
handleNonCriticalError(error, {
action: 'Fetch photo submission items',
metadata: { submissionId }
});
setError(errorMsg);
setPhotos([]);
} finally {