React Query provides powerful error handling and retry mechanisms to help developers build more robust applications:
Error Handling
-
Basic error handling:
javascriptconst { data, error, isError } = useQuery('todos', fetchTodos); if (isError) { return <div>Error: {error.message}</div>; } -
Global error handling: Configure through QueryClient
javascriptconst queryClient = new QueryClient({ defaultOptions: { queries: { onError: (error) => { console.error('Query error:', error); // Can add global error notifications here }, }, }, }); -
Mutation error handling:
javascriptconst mutation = useMutation(addTodo, { onError: (error, variables, context) => { console.error('Mutation error:', error); // Error handling logic }, });
Retry Mechanism
-
Basic retry configuration:
javascriptconst { data } = useQuery('todos', fetchTodos, { retry: 3, // Default value is 3 }); -
Advanced retry configuration:
javascriptconst { data } = useQuery('todos', fetchTodos, { retry: (failureCount, error) => { // Custom retry logic if (error.status === 404) return false; // Don't retry 404 if (failureCount >= 3) return false; // Max 3 retries return true; }, retryDelay: (attemptIndex) => { // Exponential backoff strategy return Math.min(1000 * 2 ** attemptIndex, 30000); }, });
Best Practices
-
Error boundaries: Use React error boundaries to catch query errors
javascript<ErrorBoundary fallback={<ErrorComponent />}> <QueryComponent /> </ErrorBoundary> -
Error state UI: Provide different UI feedback for different error types
javascriptif (isError) { if (error.status === 401) { return <div>Please log in first</div>; } else if (error.status === 404) { return <div>Resource not found</div>; } else { return <div>Error: {error.message}</div>; } } -
Retry strategies:
- Use retries for network errors
- Use retries for 5xx server errors
- Don't use retries for 4xx client errors (like 401, 404)
-
Error logging: Integrate with error monitoring services (like Sentry)
javascriptconst queryClient = new QueryClient({ defaultOptions: { queries: { onError: (error) => { Sentry.captureException(error); }, }, }, }); -
User feedback:
- Show loading states
- Display error messages
- Provide retry buttons
-
Optimistic update error handling: Properly handle rollbacks in mutations
javascriptconst mutation = useMutation(updateTodo, { onMutate: () => { /* Optimistic update */ }, onError: (error, variables, context) => { // Rollback data queryClient.setQueryData('todos', context.previousTodos); // Show error message showNotification('Update failed', 'error'); }, });
By properly configuring error handling and retry mechanisms, you can significantly improve your application's reliability and user experience.